how to get user appdata path from windows service by running service under local profile

588 Views Asked by At

I have written a Windows service that allows me to execute an application.exe by using CreateProcessASUser().

HANDLE hTokenDup = NULL;
DuplicateTokenEx(auToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &hTokenDup);
CreateProcessAsUserW(hTokenDup, NULL, cmdLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);

and This is my application source cod:

    static bool first = true;

    TCHAR* getAppDataFolder() {
        TCHAR* pathTchar = (TCHAR*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (_MAX_PATH + 1) * sizeof(TCHAR));
        BOOL getAppdata = SHGetSpecialFolderPath(0, pathTchar, CSIDL_APPDATA, false );


        return pathTchar;
    }

    BOOL WriteFileFromWCHAR(HANDLE hFile, 
LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
 LPDWORD lpNumberOfBytesWritten)
    {
        BYTE* arr = new BYTE[nNumberOfBytesToWrite];
        TCHAR* buff = (TCHAR*)lpBuffer;
        for(int i = 0; i < nNumberOfBytesToWrite; i++) {
            arr[i] = (BYTE)buff[i];
        }
        return WriteFile( hFile , arr , nNumberOfBytesToWrite , lpNumberOfBytesWritten, NULL);
    }

    int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmd, int show)
    {
        int argc = 0;
        _TCHAR** argv;

        LPTSTR cmdLine = GetCommandLine();
        argv = CommandLineToArgvW(cmdLine, &argc );



        if(argc == 2) {

            TCHAR* path = getAppDataFolder();


            HANDLE hFile = CreateFile( argv[1] , GENERIC_WRITE , 0 , NULL  , CREATE_ALWAYS , 0 , 0 );
            if ( hFile != INVALID_HANDLE_VALUE )
            {

                DWORD lpNumberOfBytesWritten;

                WriteFileFromWCHAR(hFile, path, lstrlen(path), &lpNumberOfBytesWritten);
            }
            else {

            }




        }
        return 0;
    }

I need to write this address(for example : "C:\Users\CurrentUser\AppData\Roaming") in file. But when I retrieve the appdata path from windows service i get following path "C:\Windows\system32\config\systemprofile\AppData\Roming" . How do I code in C++ to allow my service to execute the application and write the expected path on file?

1

There are 1 best solutions below

0
On

You have to impersonate the user (you already have the user's token) before using any APIs that are dependent on user-specific settings. Also you need to call LoadUserProfile() (using that same token) before calling CreateProcessAsUser().