Esempio n. 1
0
static int
pioctl_int(char *pathp, afs_int32 opcode, struct ViceIoctl *blobp, afs_int32 follow, afs_int32 is_utf8)
{
    fs_ioctlRequest_t preq;
    long code;
    long temp;
    char fullPath[1000];
    char altPath[1024];
    HANDLE reqHandle;
    int save;
    int i,j,count,all;

    /*
     * The pioctl operations for creating a mount point and a symlink are broken.
     * Instead of 'pathp' referring to the directory object in which the symlink
     * or mount point within which the new object is to be created, 'pathp' refers
     * to the object itself.  This results in a problem when the object being created
     * is located within the Freelance root.afs volume.  \\afs\foo will not be a
     * valid share name since the 'foo' object does not yet exist.  Therefore,
     * \\afs\foo\_._.afs_ioctl_._ cannot be opened.  Instead in these two cases
     * we must force the use of the \\afs\all\foo form of the path.
     *
     * We cannot use this form in all cases because of smb submounts which are
     * not located within the Freelance local root.
     */
    switch ( opcode ) {
    case VIOC_AFS_CREATE_MT_PT:
    case VIOC_SYMLINK:
        if (pathp &&
             (pathp[0] == '\\' && pathp[1] == '\\' ||
              pathp[0] == '/' && pathp[1] == '/')) {
            for (all = count = j = 0; pathp[j]; j++) {
                if (pathp[j] == '\\' || pathp[j] == '/')
                    count++;

                /* Test to see if the second component is 'all' */
                if (count == 3) {
                    all = 1;
                    for (i=0; pathp[i+j]; i++) {
                        switch(i) {
                        case 0:
                            if (pathp[i+j] != 'a' &&
                                pathp[i+j] != 'A') {
                                all = 0;
                                goto notall;
                            }
                            break;
                        case 1:
                        case 2:
                            if (pathp[i+j] != 'l' &&
                                 pathp[i+j] != 'L') {
                                all = 0;
                                goto notall;
                            }
                            break;
                        default:
                            all = 0;
                            goto notall;
                        }
                    }
                    if (i != 3)
                        all = 0;
                }

              notall:
                if (all)
                    break;
            }

            /*
             * if count is three and the second component is not 'all',
             * then we are attempting to create an object in the
             * Freelance root.afs volume.  Substitute the path.
             */

            if (count == 3 && !all) {
                /* Normalize the name to use \\afs\all as the root */
                for (count = i = j = 0; pathp[j] && i < sizeof(altPath); j++) {
                    if (pathp[j] == '\\' || pathp[j] == '/') {
                        altPath[i++] = '\\';
                        count++;

                        if (count == 3) {
                            altPath[i++] = 'a';
                            altPath[i++] = 'l';
                            altPath[i++] = 'l';
                            altPath[i++] = '\\';
                            count++;
                        }
                    } else {
                        altPath[i++] = pathp[j];
                    }
                }
                altPath[i] = '\0';
                pathp = altPath;
            }
        }
    }

    code = GetIoctlHandle(pathp, &reqHandle);
    if (code) {
	if (pathp)
	    errno = EINVAL;
	else
	    errno = ENODEV;
	return code;
    }

    /* init the request structure */
    InitFSRequest(&preq);

    /* marshall the opcode, the path name and the input parameters */
    MarshallLong(&preq, opcode);
    /* when marshalling the path, remove the drive letter, since we already
     * used the drive letter to find the AFS daemon; we don't need it any more.
     * Eventually we'll expand relative path names here, too, since again, only
     * we understand those.
     */
    if (pathp) {
	code = fs_GetFullPath(pathp, fullPath, sizeof(fullPath));
	if (code) {
	    CloseHandle(reqHandle);
	    errno = EINVAL;
	    return code;
	}
    } else {
	strcpy(fullPath, "");
    }

    MarshallString(&preq, fullPath, is_utf8);
    if (blobp->in_size) {
        if (blobp->in_size > sizeof(preq.data) - (preq.mp - preq.data)*sizeof(char)) {
            errno = E2BIG;
            return -1;
        }
	memcpy(preq.mp, blobp->in, blobp->in_size);
	preq.mp += blobp->in_size;
    }

    /* now make the call */
    code = Transceive(reqHandle, &preq);
    if (code) {
	CloseHandle(reqHandle);
	return code;
    }

    /* now unmarshall the return value */
    if (UnmarshallLong(&preq, &temp) != 0) {
        CloseHandle(reqHandle);
        return -1;
    }

    if (temp != 0) {
	CloseHandle(reqHandle);
	errno = CMtoUNIXerror(temp);
        if ( IoctlDebug() ) {
            save = errno;
            fprintf(stderr, "pioctl temp != 0: 0x%X\r\n",temp);
            errno = save;
        }
	return -1;
    }

    /* otherwise, unmarshall the output parameters */
    if (blobp->out_size) {
	temp = blobp->out_size;
	if (preq.nbytes < temp)
	    temp = preq.nbytes;
	memcpy(blobp->out, preq.mp, temp);
	blobp->out_size = temp;
    }

    /* and return success */
    CloseHandle(reqHandle);
    return 0;
}
Esempio n. 2
0
BOOL CreateRemoteSessionProcess(
        IN DWORD        dwSessionId,
        IN BOOL         bUseDefaultToken,
        IN HANDLE       hToken,
        IN LPCWSTR      lpApplicationName,
        IN LPSTR       A_lpCommandLine,
        IN LPSECURITY_ATTRIBUTES lpProcessAttributes,
        IN LPSECURITY_ATTRIBUTES lpThreadAttributes,
        IN BOOL bInheritHandles,
        IN DWORD dwCreationFlags,
        IN LPVOID lpEnvironment,
        IN LPCWSTR lpCurrentDirectory,
        IN LPSTARTUPINFO A_lpStartupInfo,
        OUT LPPROCESS_INFORMATION lpProcessInformation)
{

		WCHAR       lpCommandLine[255];
		STARTUPINFOW StartupInfo;
		Char2Wchar(lpCommandLine, A_lpCommandLine, 255);
		ZeroMemory(&StartupInfo,sizeof(STARTUPINFOW));
		StartupInfo.wShowWindow = SW_SHOW;
		StartupInfo.lpDesktop = L"Winsta0\\Winlogon";
		StartupInfo.cb = sizeof(STARTUPINFOW);

        WCHAR           szWinStaPath[MAX_PATH];
        BOOL            bGetNPName=FALSE;
        WCHAR           szNamedPipeName[MAX_PATH]=L"";
        DWORD           dwNameLen;
        HINSTANCE       hInstWinSta;
        HANDLE          hNamedPipe;
        LPVOID          pData=NULL;
        BOOL            bRet = FALSE;
        DWORD           cbReadBytes,cbWriteBytes;
        DWORD           dwEnvLen = 0;
        union{
                CPAU_PARAM      cpauData;
                BYTE            bDump[0x2000];
        };
        CPAU_RET_PARAM  cpauRetData;
        DWORD                   dwUsedBytes = sizeof(cpauData);
        LPBYTE                  pBuffer = (LPBYTE)(&cpauData+1);
        GetSystemDirectoryW(szWinStaPath, MAX_PATH);
        lstrcatW(szWinStaPath,L"\\winsta.dll");
        hInstWinSta = LoadLibraryW(szWinStaPath);

        if(hInstWinSta)
        {
                pWinStationQueryInformationW pfWinStationQueryInformationW=(pWinStationQueryInformationW)GetProcAddress(hInstWinSta,"WinStationQueryInformationW");
                if(pfWinStationQueryInformationW)
                {
                        bGetNPName = pfWinStationQueryInformationW(0, dwSessionId, 0x21,szNamedPipeName, sizeof(szNamedPipeName), &dwNameLen);
                }
                FreeLibrary(hInstWinSta);
        }
        if(!bGetNPName || szNamedPipeName[0] == '\0')
        {
                swprintf(szNamedPipeName,260,L"\\\\.\\Pipe\\TerminalServer\\SystemExecSrvr\\%d", dwSessionId);
        }

        do{
                hNamedPipe = CreateFileW(szNamedPipeName, GENERIC_READ|GENERIC_WRITE,0, NULL, OPEN_EXISTING, 0, 0);
                if(hNamedPipe == INVALID_HANDLE_VALUE)
                {
                        if(GetLastError() == ERROR_PIPE_BUSY)
                        {
                                if(!WaitNamedPipeW(szNamedPipeName, 30000))
                                        return FALSE;
                        }
                        else
                        {
                                return FALSE;
                        }
                }
        }while(hNamedPipe == INVALID_HANDLE_VALUE);

        memset(&cpauData, 0, sizeof(cpauData));
        cpauData.bInheritHandles        = bInheritHandles;
        cpauData.bUseDefaultToken       = bUseDefaultToken;
        cpauData.dwCreationFlags        = dwCreationFlags;
        cpauData.dwProcessId            = GetCurrentProcessId();
        cpauData.hToken                         = hToken;
        cpauData.lpApplicationName      =(LPWSTR)MarshallString(lpApplicationName, &cpauData, sizeof(bDump),&pBuffer, &dwUsedBytes);
        cpauData.lpCommandLine          = (LPWSTR)MarshallString(lpCommandLine,&cpauData, sizeof(bDump), &pBuffer, &dwUsedBytes);
        cpauData.StartupInfo            = StartupInfo;
        cpauData.StartupInfo.lpDesktop  =(LPWSTR)MarshallString(cpauData.StartupInfo.lpDesktop, &cpauData,sizeof(bDump), &pBuffer, &dwUsedBytes);
        cpauData.StartupInfo.lpTitle    =(LPWSTR)MarshallString(cpauData.StartupInfo.lpTitle, &cpauData,sizeof(bDump), &pBuffer, &dwUsedBytes);

        if(lpEnvironment)
        {
                if(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT)
                {
                        while((dwEnvLen+dwUsedBytes <= sizeof(bDump)))
                        {
                                if(((LPWSTR)lpEnvironment)[dwEnvLen/2]=='\0' &&((LPWSTR)lpEnvironment)[dwEnvLen/2+1] == '\0')
                                {
                                        dwEnvLen+=2*sizeof(WCHAR);
                                        break;
                                }
                                dwEnvLen+=sizeof(WCHAR);
                        }
                }
                else
                {
                        while(dwEnvLen+dwUsedBytes <= sizeof(bDump))
                        {
                                if(((LPSTR)lpEnvironment)[dwEnvLen]=='\0' && ((LPSTR)lpEnvironment)[dwEnvLen+1]=='\0')
                                {
                                        dwEnvLen+=2;
                                        break;
                                }
                                dwEnvLen++;
                        }
                }
                if(dwEnvLen+dwUsedBytes <= sizeof(bDump))
                {
                        memmove(pBuffer, lpEnvironment, dwEnvLen);
                        cpauData.lpEnvironment = (LPVOID)dwUsedBytes;
                        pBuffer += dwEnvLen;
                        dwUsedBytes += dwEnvLen;
                }
                else
                {
                        cpauData.lpEnvironment = NULL;
                }
        }
        else
        {
                cpauData.lpEnvironment  = NULL;
        }
        cpauData.cbSize  = dwUsedBytes;

		HANDLE hProcess=NULL;
        if(WriteFile(hNamedPipe, &cpauData, cpauData.cbSize, &cbWriteBytes,NULL))
		{
			Sleep(250);
			if (ReadFile(hNamedPipe, & cpauRetData, sizeof(cpauRetData),&cbReadBytes, NULL))
			{
				hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, cpauRetData.ProcInfo.dwProcessId);
	#ifdef _DEBUG
						char			szText[256];
						sprintf(szText," ++++++cpau  %i  %i %i %i %i %i\n",cpauRetData.bRetValue,cpauRetData.ProcInfo.hProcess,cpauRetData.ProcInfo.dwProcessId,cpauRetData.ProcInfo.dwThreadId,cpauRetData.ProcInfo.hThread,hProcess);
						OutputDebugString(szText);						
	#endif
					bRet = cpauRetData.bRetValue;
					if(bRet)
					{
							*lpProcessInformation = cpauRetData.ProcInfo;
					}
					else
							SetLastError(cpauRetData.dwLastErr);
			}
		}
        else
                bRet = FALSE;
		// function sometimes fail, the use processid to get hprocess... bug MS
		if (lpProcessInformation->hProcess==0) lpProcessInformation->hProcess=hProcess;
		//this should never happen, looping connections
		if (lpProcessInformation->hProcess==0) 
			Sleep(5000);
        CloseHandle(hNamedPipe);
        return bRet;

}