Search code examples
cwindowswinapiargvwidechar

Wide string command line arguments in C


I'm writing a program that what it does first, is to retrieve the first command line argument (which should be a process name), and find the corresponding PID of the process.

Here's how I do it:

in main

DWORD PID = FindProcessId(argv[1]);

and here's the function that finds PID:

DWORD FindProcessId(PWCHAR processname)
{
    NTSTATUS status;
    PVOID buffer;
    PSYSTEM_PROCESS_INFORMATION spi;
    DWORD pid = 0;

    buffer = VirtualAlloc(NULL, 1024 * 1024, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
    spi = (PSYSTEM_PROCESS_INFORMATION)buffer;

    status = NtQuerySystemInformation(SystemProcessInformation, spi, 1024 * 1024, NULL);

    while (spi->NextEntryOffset) // Loop over the list until we reach the last entry, or found PID.
    {
        if (wcsncmp(spi->ImageName.Buffer, processname, spi->ImageName.Length) == 0)
        {
            pid = spi->UniqueProcessId;
            break;
        }
        spi = (PSYSTEM_PROCESS_INFORMATION)((LPBYTE)spi + spi->NextEntryOffset); // Calculate the address of the next entry.

    }

    return pid;
}

The thing is, it works perfectly if i simply write

DWORD PID = FindProcessId(L"notepad.exe");,

for example.

But when i use the command line argument and runthe program like so: find_pid.exe notepad.exe the FindProcessId returns 0, meaning it didn't find the process. Even though notepad.exe is running like before.

Any ideas why this doesn't work with the command line argument?


To make the program accept PWCHAR rather than char * (Wide strings rather than ascii ones), I had to use main instead of wmain


Solution

  • To make the program accept PWCHAR rather than char * (Wide strings rather than ascii ones), I had to use wmain instead of main, like so:

    int wmain(int argc, PWCHAR argv[])
    {
        ....
        return 0;
    }
    

    OR

    Just convert the char * to a wide string - PWCHAR, like so:

    WCHAR victimProcessName[MAX_PATH];
    mbstowcs(victimProcessName, argv[1], MAX_PATH); // Plus null