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; }
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; }