int __cdecl main(int argc, char *argv[]) { int err; WCHAR *wpBuffer = NULL; char *pChar = NULL; unsigned long ul = 1234567890UL; char *pChar10 = "1234567890"; char *pChar2 = "1001001100101100000001011010010"; char *pChar16 = "499602d2"; /*Initialize the PAL environment*/ err = PAL_Initialize(argc, argv); if(0 != err) { return FAIL; } wpBuffer = malloc(64 * sizeof(WCHAR)); if(NULL == wpBuffer) { Fail("\nFail to allocate the buffer to save a converted " "wide character string, error code=%d!\n", GetLastError()); } /*convert to a 10 base string*/ _ui64tow(ul, wpBuffer, 10); pChar = convertC(wpBuffer); if(strcmp(pChar10, pChar)) { free(wpBuffer); free(pChar); Fail("\nFailed to call _ui64tow API to convert an interger " "to a 10 base wide character string, error code=%d\n", GetLastError()); } free(pChar); free(wpBuffer); wpBuffer = malloc(64 * sizeof(WCHAR)); if(NULL == wpBuffer) { Fail("\nFail to allocate the buffer to save a converted " "wide character string, error code=%d!\n", GetLastError()); } /*convert to a 16 base string*/ _ui64tow(ul, wpBuffer, 16); pChar = convertC(wpBuffer); if(strcmp(pChar16, pChar)) { free(wpBuffer); free(pChar); Fail("\nFailed to call _ui64tow API to convert an interger " "to a 16 base wide character string, error code = %d\n", GetLastError()); } free(pChar); free(wpBuffer); wpBuffer = malloc(64 * sizeof(WCHAR)); if(NULL == wpBuffer) { Fail("\nFail to allocate the buffer to save a converted " "wide character string, error code=%d!\n", GetLastError()); } /*convert to a 2 base string*/ _ui64tow(ul, wpBuffer, 2); pChar = convertC(wpBuffer); if(strcmp(pChar2, pChar)) { free(wpBuffer); free(pChar); Fail("\nFailed to call _ui64tow API to convert an interger " "to a 2 base wide character string, error code=%d\n", GetLastError()); } free(pChar); free(wpBuffer); PAL_Terminate(); return PASS; }
//----------------------------------------------------------------------------- static void process_dir_watcher_results( watch_entry *watch_entry_p, DWORD buffer_size){ //----------------------------------------------------------------------------- HANDLE hChangeLog; PFILE_NOTIFY_INFORMATION buffer_p; DWORD buffer_index; BOOL more; SSIZE_T path_len; int compare_result; BOOL exclude; struct exclude_entry * exclude_entry_p; DWORD error_code; errno_t copy_result; LPWSTR fmt, slash_pos; hChangeLog = INVALID_HANDLE_VALUE; more = TRUE; buffer_index = 0; // If buffer size is 0, indicates that too many changes occurred to fit in the buffer // Write out the top level dir to trigger the monitor to do a full pass of it if (buffer_size == 0){ more = FALSE; copy_result = wcsncpy_s(full_file_name, ARRAYSIZE(full_file_name), watch_entry_p->dir_path, watch_entry_p->dir_path_len); if (copy_result != 0){ report_error(L"wcsncpy_s failed", copy_result); ExitProcess(28); } write_path_to_temp_file(full_file_name, ARRAYSIZE(full_file_name), &hChangeLog); } while (more) { buffer_p = (PFILE_NOTIFY_INFORMATION) &watch_entry_p->changes_buffer[buffer_index]; // Cannot use just sizeof(FILE_NOTIFY_INFORMATION) as it includes 2 bytes of struct padding, // causing this check to fail for single-character filenames size_t entry_size = offsetof(FILE_NOTIFY_INFORMATION, FileName) + buffer_p->FileNameLength; if ((buffer_index + entry_size) > buffer_size) { _wfopen_s(&error_file, error_path, L"w"); fwprintf( error_file, L"process_dir_watcher_results buffer overrun %d %d\n", buffer_index, buffer_size ); fclose(error_file); ExitProcess(18); } copy_result = wcsncpy_s(relative_file_name, ARRAYSIZE(relative_file_name), buffer_p->FileName, buffer_p->FileNameLength/sizeof(wchar_t)); if (copy_result != 0){ report_error(L"wcsncpy_s failed", copy_result); ExitProcess(25); } // 2010-09-05 dougfort -- if the dir_path ends in a slash // (probably something like c:\) then we don't want to // interpolate another slash if (watch_entry_p->dir_path[watch_entry_p->dir_path_len-1] == L'\\') fmt = L"%s%s"; else fmt = L"%s\\%s"; path_len = _snwprintf_s(full_file_name, ARRAYSIZE(full_file_name), _TRUNCATE, fmt, watch_entry_p->dir_path, relative_file_name); if (path_len == -1){ report_error(L"_snwprintf_s failed, path too long", (DWORD)(watch_entry_p->dir_path_len + wcslen(relative_file_name))); ExitProcess(26); } // We want the directory where the event took place, // for consistency with OSX. // Needs to be done before calling GetLongPathName since in the case of // a rename or delete the actual file itself is already gone if (full_file_name[path_len-1] != L'\\') { slash_pos = wcsrchr(full_file_name, L'\\'); if (slash_pos) *slash_pos = L'\0'; } // Need to translate short names before checking excludes // According to MSDN docs, you can reuse the same buffer for output path_len = GetLongPathNameW( full_file_name, full_file_name, ARRAYSIZE(full_file_name) ); // Note that most of errors that occurred here were due to a buffer overflow // which has since been fixed. In case of error, pass orig filename unchanged and // let code that picks up output deal with removed folders, etc if (path_len == 0) { error_code = GetLastError(); report_error(L"GetLongPathNameW", error_code); path_len=wcslen(full_file_name); } else if (path_len > ARRAYSIZE(full_file_name)){ // Shouldn't happen since buffer is maximum possible path length report_error(L"GetLongPathNameW result would overflow buffer", (DWORD)path_len); ExitProcess(27); } // Can check for excludes last since we only ever exclude folders exclude = FALSE; for ( exclude_entry_p=exclude_entry_list_p; exclude_entry_p != NULL; exclude_entry_p = exclude_entry_p->next_p ) { compare_result = _wcsnicmp( full_file_name, exclude_entry_p->dir_path, exclude_entry_p->dir_path_len ); if (0 == compare_result) { exclude = TRUE; break; } } if (exclude) { if (0 == buffer_p->NextEntryOffset) { more = FALSE; } else { buffer_index += buffer_p->NextEntryOffset; } continue; } write_path_to_temp_file(full_file_name, ARRAYSIZE(full_file_name), &hChangeLog); if (0 == buffer_p->NextEntryOffset) { more = FALSE; } else { buffer_index += buffer_p->NextEntryOffset; } } // while (more) if (hChangeLog != INVALID_HANDLE_VALUE) { CloseHandle(hChangeLog); notification_sequence++; wsprintf( notification_file_path, // LPTSTR pszDest, L"%s\\%08d.txt", // LPCTSTR pszFormat notification_path, notification_sequence ); if (_wrename(temp_file_path, notification_file_path) != 0) { _wfopen_s(&error_file, error_path, L"w"); _wcserror_s( error_buffer, sizeof error_buffer/sizeof(wchar_t), errno ); fwprintf( error_file, L"_wrename(%s, %s) failed: (%d) %s\n", temp_file_path, notification_file_path, errno, error_buffer ); fclose(error_file); ExitProcess(24); } } } // static void process_dir_watcher_results(
void MI_CALL MSFT_DSCLocalConfigManager_Invoke_SendConfigurationApply( _In_opt_ MSFT_DSCLocalConfigManager_Self* self, _In_ MI_Context* context, _In_opt_z_ const MI_Char* nameSpace, _In_opt_z_ const MI_Char* className, _In_opt_z_ const MI_Char* methodName, _In_ const MSFT_DSCLocalConfigManager* instanceName, _In_opt_ const MSFT_DSCLocalConfigManager_SendConfigurationApply* in) { MI_Result miResult; MI_Instance *cimErrorDetails = NULL; MI_Uint32 bufferIndex = 0; HANDLE m_clientThreadToken; MI_UNREFERENCED_PARAMETER(self); MI_UNREFERENCED_PARAMETER(nameSpace); MI_UNREFERENCED_PARAMETER(className); MI_UNREFERENCED_PARAMETER(methodName); MI_UNREFERENCED_PARAMETER(instanceName); MI_UNREFERENCED_PARAMETER(in); if(!in->ConfigurationData.exists) { MI_Context_PostResult(context, MI_RESULT_INVALID_PARAMETER); return; } if(!OpenThreadToken(GetCurrentThread(), TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_DUPLICATE, TRUE, &m_clientThreadToken)) { GetCimWin32Error(GetLastError(), &cimErrorDetails, ID_LCMHELPER_THREADIMPERSONATION_FAILED); MI_PostCimError(context, cimErrorDetails); MI_Instance_Delete(cimErrorDetails); return; } if (!SetThreadToken(NULL, NULL)) { GetCimWin32Error(GetLastError(), &cimErrorDetails, ID_LCMHELPER_REVERTSELF_FAILED); MI_PostCimError(context, cimErrorDetails); MI_Instance_Delete(cimErrorDetails); CloseHandle(m_clientThreadToken); return; } GetRealBufferIndex( &(in->ConfigurationData.value), &bufferIndex); miResult = CallSetConfiguration(in->ConfigurationData.value.data + bufferIndex, in->ConfigurationData.value.size - bufferIndex, LCM_SETFLAGS_DEFAULT, context, &cimErrorDetails); if (!SetThreadToken(NULL, m_clientThreadToken)) { GetCimWin32Error(GetLastError(), &cimErrorDetails, ID_LCMHELPER_RESUMEIMPERSONATION_FAILED); MI_PostCimError(context, cimErrorDetails); MI_Instance_Delete(cimErrorDetails); CloseHandle(m_clientThreadToken); return; } CloseHandle(m_clientThreadToken); if(miResult != MI_RESULT_OK) { MI_PostCimError(context, cimErrorDetails); MI_Instance_Delete(cimErrorDetails); return; } MI_Context_PostResult(context, MI_RESULT_OK); }
teUtilsStatus eUtils_QueueDequeueTimed(tsUtilsQueue *psQueue, uint32_t u32WaitMs, void **ppvData) { tsQueuePrivate *psQueuePrivate = (tsQueuePrivate*)psQueue->pvPriv; #ifndef WIN32 pthread_mutex_lock (&psQueuePrivate->mMutex); #else EnterCriticalSection (&psQueuePrivate->hMutex); #endif /* WIN32 */ while (psQueuePrivate->u32Size == 0) { #ifndef WIN32 struct timeval sNow; struct timespec sTimeout; memset(&sNow, 0, sizeof(struct timeval)); gettimeofday(&sNow, NULL); sTimeout.tv_sec = sNow.tv_sec + (u32WaitMs/1000); sTimeout.tv_nsec = (sNow.tv_usec + ((u32WaitMs % 1000) * 1000)) * 1000; if (sTimeout.tv_nsec > 1000000000) { sTimeout.tv_sec++; sTimeout.tv_nsec -= 1000000000; } //DBG_vPrintf(DBG_QUEUE, "Dequeue timed: now %lu s, %lu ns\n", sNow.tv_sec, sNow.tv_usec * 1000); //DBG_vPrintf(DBG_QUEUE, "Dequeue timed: until %lu s, %lu ns\n", sTimeout.tv_sec, sTimeout.tv_nsec); switch (pthread_cond_timedwait(&psQueuePrivate->cond_data_available, &psQueuePrivate->mMutex, &sTimeout)) #else // Set n = 0 for success or the error code. int n = 0; if (!SleepConditionVariableCS(&psQueuePrivate->hDataAvailable, &psQueuePrivate->hMutex, u32WaitMs)) { n = GetLastError(); } switch(n) #endif /* WIN32 */ { case (0): break; #ifndef WIN32 case (ETIMEDOUT): pthread_mutex_unlock(&psQueuePrivate->mMutex); #else case (ERROR_TIMEOUT): LeaveCriticalSection(&psQueuePrivate->hMutex); #endif /* WIN32 */ return E_UTILS_ERROR_TIMEOUT; default: #ifndef WIN32 pthread_mutex_unlock(&psQueuePrivate->mMutex); #else LeaveCriticalSection(&psQueuePrivate->hMutex); #endif /* WIN32 */ return E_UTILS_ERROR_FAILED; } } *ppvData = psQueuePrivate->apvBuffer[psQueuePrivate->u32Out]; --psQueuePrivate->u32Size; DBG_vPrintf(DBG_QUEUE, "Queue %p (size=%d)\n", psQueue, psQueuePrivate->u32Size); psQueuePrivate->u32Out = (psQueuePrivate->u32Out + 1) % psQueuePrivate->u32Capacity; #ifndef WIN32 pthread_mutex_unlock (&psQueuePrivate->mMutex); pthread_cond_broadcast (&psQueuePrivate->cond_space_available); #else LeaveCriticalSection (&psQueuePrivate->hMutex); WakeConditionVariable (&psQueuePrivate->hSpaceAvailable); #endif /* WIN32 */ return E_UTILS_OK; }
//----------------------------------------------------------------------------- static void load_paths_to_watch(LPCTSTR path, HANDLE completion_port_h) { //----------------------------------------------------------------------------- FILE * stream_p; wchar_t *get_result; HANDLE create_result; size_t line_len; struct watch_entry **link_p; struct watch_entry * next_p; if (_wfopen_s(&stream_p, path, L"r, ccs=UTF-8")) { _wfopen_s(&error_file, error_path, L"w"); _wcserror_s(error_buffer, ARRAYSIZE(error_buffer), errno); fwprintf( error_file, L"_wfopen(%s) failed: (%d) %s\n", path, errno, error_buffer ); fclose(error_file); ExitProcess(2); } link_p = &watch_entry_list_p; while (1) { // create a watch entry next_p = (struct watch_entry *) HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct watch_entry) ); if (next_p == NULL){ report_error(L"HeapAlloc failed to allocate memory", GetLastError()); ExitProcess(200); } // read in the path to watch from config.txt get_result = \ fgetws(full_file_name, ARRAYSIZE(full_file_name), stream_p); if (NULL == get_result) { if (0 == ferror(stream_p)) { HeapFree(GetProcessHeap(), 0, next_p); break; } _wfopen_s(&error_file, error_path, L"w"); _wcserror_s( error_buffer, sizeof error_buffer/sizeof(wchar_t) , errno ); fwprintf( error_file, L"fgetws(%s) failed: (%d) %s\n", path, errno, error_buffer ); fclose(error_file); ExitProcess(2); } // clean out the newline, if there is one line_len = wcslen(full_file_name); if (line_len && full_file_name[line_len-1] == L'\n'){ full_file_name[line_len-1] = L'\0'; line_len--; } if (full_file_name[0] == L'\0') continue; next_p->dir_path_len = line_len; next_p->dir_path = (wchar_t *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (line_len + 1) * sizeof(wchar_t)); if (next_p->dir_path == NULL){ report_error(L"HeapAlloc failed to allocate memory", GetLastError()); ExitProcess(201); } wcsncpy_s(next_p->dir_path, line_len+1, full_file_name, line_len); next_p->changes_buffer = (BYTE *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, CHANGES_BUFFER_SIZE); if (next_p->changes_buffer == NULL){ report_error(L"HeapAlloc failed to allocate memory", GetLastError()); ExitProcess(202); } // 2020-09-05 dougfort -- we don't clean out trailing slash here // because if they are backing up something like c:\\, we need // the trailing slash. This will come back to bite us when we are // checking for excludes // open a file handle to watch the directory in overlapped mode next_p->hDirectory = CreateFile( next_p->dir_path, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, NULL ); // 2009-03-11 dougfort -- if we can't create this file, // assume it is a top-level directory // which no longer exists; so ignore it and move on. if (INVALID_HANDLE_VALUE == next_p->hDirectory) { report_error(L"CreateFile", GetLastError()); continue; } // add this file handle to the IO Complete port create_result = CreateIoCompletionPort( next_p->hDirectory, // FileHandle, completion_port_h, // ExistingCompletionPort, 0, // CompletionKey, 0 // NumberOfConcurrentThreads ); if (NULL == create_result) { report_error(L"CreateIOCompletionPort (add)", GetLastError()); ExitProcess(102); } if (create_result != completion_port_h) { ExitProcess(103); } start_watch(next_p); // add this entry to the list *link_p = next_p; // point to the new entry's next pointer link_p = &(*link_p)->next_p; } // while(1) fclose(stream_p); } // load_paths_to_watch
// Copies all file sectors into another archive. static int CopyMpqFileSectors( TMPQArchive * ha, TMPQFile * hf, TFileStream * pNewStream) { TFileEntry * pFileEntry = hf->pFileEntry; ULONGLONG RawFilePos; // Used for calculating sector offset in the old MPQ archive ULONGLONG MpqFilePos; // MPQ file position in the new archive DWORD dwBytesToCopy = pFileEntry->dwCmpSize; DWORD dwPatchSize = 0; // Size of patch header DWORD dwFileKey1 = 0; // File key used for decryption DWORD dwFileKey2 = 0; // File key used for encryption DWORD dwCmpSize = 0; // Compressed file size, including patch header int nError = ERROR_SUCCESS; // Remember the position in the destination file FileStream_GetPos(pNewStream, MpqFilePos); MpqFilePos -= ha->MpqPos; // Resolve decryption keys. Note that the file key given // in the TMPQFile structure also includes the key adjustment if(nError == ERROR_SUCCESS && (pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED)) { dwFileKey2 = dwFileKey1 = hf->dwFileKey; if(pFileEntry->dwFlags & MPQ_FILE_FIX_KEY) { dwFileKey2 = (dwFileKey1 ^ pFileEntry->dwFileSize) - (DWORD)pFileEntry->ByteOffset; dwFileKey2 = (dwFileKey2 + (DWORD)MpqFilePos) ^ pFileEntry->dwFileSize; } } // If we have to save patch header, do it if(nError == ERROR_SUCCESS && hf->pPatchInfo != NULL) { BSWAP_ARRAY32_UNSIGNED(hf->pPatchInfo, sizeof(DWORD) * 3); if(!FileStream_Write(pNewStream, NULL, hf->pPatchInfo, hf->pPatchInfo->dwLength)) nError = GetLastError(); // Save the size of the patch info dwPatchSize = hf->pPatchInfo->dwLength; } // If we have to save sector offset table, do it. if(nError == ERROR_SUCCESS && hf->SectorOffsets != NULL) { DWORD * SectorOffsetsCopy = (DWORD *)STORM_ALLOC(BYTE, hf->SectorOffsets[0]); DWORD dwSectorOffsLen = hf->SectorOffsets[0]; assert((pFileEntry->dwFlags & MPQ_FILE_SINGLE_UNIT) == 0); assert(pFileEntry->dwFlags & MPQ_FILE_COMPRESSED); if(SectorOffsetsCopy == NULL) nError = ERROR_NOT_ENOUGH_MEMORY; // Encrypt the secondary sector offset table and write it to the target file if(nError == ERROR_SUCCESS) { memcpy(SectorOffsetsCopy, hf->SectorOffsets, dwSectorOffsLen); if(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED) EncryptMpqBlock(SectorOffsetsCopy, dwSectorOffsLen, dwFileKey2 - 1); BSWAP_ARRAY32_UNSIGNED(SectorOffsetsCopy, dwSectorOffsLen); if(!FileStream_Write(pNewStream, NULL, SectorOffsetsCopy, dwSectorOffsLen)) nError = GetLastError(); dwCmpSize += dwSectorOffsLen; } // Update compact progress if(CompactCB != NULL) { CompactBytesProcessed += dwSectorOffsLen; CompactCB(pvUserData, CCB_COMPACTING_FILES, CompactBytesProcessed, CompactTotalBytes); } STORM_FREE(SectorOffsetsCopy); } // Now we have to copy all file sectors. We do it without // recompression, because recompression is not necessary in this case if(nError == ERROR_SUCCESS) { for(DWORD dwSector = 0; dwSector < hf->dwSectorCount; dwSector++) { DWORD dwRawDataInSector = hf->dwSectorSize; DWORD dwRawByteOffset = dwSector * hf->dwSectorSize; // Last sector: If there is not enough bytes remaining in the file, cut the raw size if(dwRawDataInSector > dwBytesToCopy) dwRawDataInSector = dwBytesToCopy; // Fix the raw data length if the file is compressed if(hf->SectorOffsets != NULL) { dwRawDataInSector = hf->SectorOffsets[dwSector+1] - hf->SectorOffsets[dwSector]; dwRawByteOffset = hf->SectorOffsets[dwSector]; } // Calculate the raw file offset of the file sector CalculateRawSectorOffset(RawFilePos, hf, dwRawByteOffset); // Read the file sector if(!FileStream_Read(ha->pStream, &RawFilePos, hf->pbFileSector, dwRawDataInSector)) { nError = GetLastError(); break; } // If necessary, re-encrypt the sector // Note: Recompression is not necessary here. Unlike encryption, // the compression does not depend on the position of the file in MPQ. if((pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED) && dwFileKey1 != dwFileKey2) { BSWAP_ARRAY32_UNSIGNED(hf->pbFileSector, dwRawDataInSector); DecryptMpqBlock(hf->pbFileSector, dwRawDataInSector, dwFileKey1 + dwSector); EncryptMpqBlock(hf->pbFileSector, dwRawDataInSector, dwFileKey2 + dwSector); BSWAP_ARRAY32_UNSIGNED(hf->pbFileSector, dwRawDataInSector); } // Now write the sector back to the file if(!FileStream_Write(pNewStream, NULL, hf->pbFileSector, dwRawDataInSector)) { nError = GetLastError(); break; } // Update compact progress if(CompactCB != NULL) { CompactBytesProcessed += dwRawDataInSector; CompactCB(pvUserData, CCB_COMPACTING_FILES, CompactBytesProcessed, CompactTotalBytes); } // Adjust byte counts dwBytesToCopy -= hf->dwSectorSize; dwCmpSize += dwRawDataInSector; } } // Copy the sector CRCs, if any // Sector CRCs are always compressed (not imploded) and unencrypted if(nError == ERROR_SUCCESS && hf->SectorOffsets != NULL && hf->SectorChksums != NULL) { DWORD dwCrcLength; dwCrcLength = hf->SectorOffsets[hf->dwSectorCount + 1] - hf->SectorOffsets[hf->dwSectorCount]; if(dwCrcLength != 0) { if(!FileStream_Read(ha->pStream, NULL, hf->SectorChksums, dwCrcLength)) nError = GetLastError(); if(!FileStream_Write(pNewStream, NULL, hf->SectorChksums, dwCrcLength)) nError = GetLastError(); // Update compact progress if(CompactCB != NULL) { CompactBytesProcessed += dwCrcLength; CompactCB(pvUserData, CCB_COMPACTING_FILES, CompactBytesProcessed, CompactTotalBytes); } // Size of the CRC block is also included in the compressed file size dwCmpSize += dwCrcLength; } } // Write the MD5's of the raw file data, if needed if(nError == ERROR_SUCCESS && ha->pHeader->dwRawChunkSize != 0) { nError = WriteMpqDataMD5(pNewStream, ha->MpqPos + MpqFilePos, pFileEntry->dwCmpSize, ha->pHeader->dwRawChunkSize); } // Update file position in the block table if(nError == ERROR_SUCCESS) { // At this point, number of bytes written should be exactly // the same like the compressed file size. If it isn't, // there's something wrong (an unknown archive version, MPQ protection, ...) // // Note: Diablo savegames have very weird layout, and the file "hero" // seems to have improper compressed size. Instead of real compressed size, // the "dwCmpSize" member of the block table entry contains // uncompressed size of file data + size of the sector table. // If we compact the archive, Diablo will refuse to load the game // Seems like some sort of protection to me. // // Note: Some patch files in WOW patches don't count the patch header // into compressed size // if(dwCmpSize <= pFileEntry->dwCmpSize && pFileEntry->dwCmpSize <= dwCmpSize + dwPatchSize) { // Note: DO NOT update the compressed size in the file entry, no matter how bad it is. pFileEntry->ByteOffset = MpqFilePos; } else { nError = ERROR_FILE_CORRUPT; assert(false); } } return nError; }
int launch_server(int server_port) { #ifdef HAVE_WIN32_PROC /* we need to start the server in the background */ /* we create a PIPE that will be used to wait for the server's "OK" */ /* message since the pipe handles must be inheritable, we use a */ /* security attribute */ HANDLE pipe_read, pipe_write; HANDLE stdout_handle, stderr_handle; SECURITY_ATTRIBUTES sa; STARTUPINFO startup; PROCESS_INFORMATION pinfo; char program_path[ MAX_PATH ]; int ret; sa.nLength = sizeof(sa); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; /* create pipe, and ensure its read handle isn't inheritable */ ret = CreatePipe( &pipe_read, &pipe_write, &sa, 0 ); if (!ret) { fprintf(stderr, "CreatePipe() failure, error %ld\n", GetLastError() ); return -1; } SetHandleInformation( pipe_read, HANDLE_FLAG_INHERIT, 0 ); /* Some programs want to launch an adb command and collect its output by * calling CreateProcess with inheritable stdout/stderr handles, then * using read() to get its output. When this happens, the stdout/stderr * handles passed to the adb client process will also be inheritable. * When starting the adb server here, care must be taken to reset them * to non-inheritable. * Otherwise, something bad happens: even if the adb command completes, * the calling process is stuck while read()-ing from the stdout/stderr * descriptors, because they're connected to corresponding handles in the * adb server process (even if the latter never uses/writes to them). */ stdout_handle = GetStdHandle( STD_OUTPUT_HANDLE ); stderr_handle = GetStdHandle( STD_ERROR_HANDLE ); if (stdout_handle != INVALID_HANDLE_VALUE) { SetHandleInformation( stdout_handle, HANDLE_FLAG_INHERIT, 0 ); } if (stderr_handle != INVALID_HANDLE_VALUE) { SetHandleInformation( stderr_handle, HANDLE_FLAG_INHERIT, 0 ); } ZeroMemory( &startup, sizeof(startup) ); startup.cb = sizeof(startup); startup.hStdInput = GetStdHandle( STD_INPUT_HANDLE ); startup.hStdOutput = pipe_write; startup.hStdError = GetStdHandle( STD_ERROR_HANDLE ); startup.dwFlags = STARTF_USESTDHANDLES; ZeroMemory( &pinfo, sizeof(pinfo) ); /* get path of current program */ GetModuleFileName( NULL, program_path, sizeof(program_path) ); ret = CreateProcess( program_path, /* program path */ "adb fork-server server", /* the fork-server argument will set the debug = 2 in the child */ NULL, /* process handle is not inheritable */ NULL, /* thread handle is not inheritable */ TRUE, /* yes, inherit some handles */ DETACHED_PROCESS, /* the new process doesn't have a console */ NULL, /* use parent's environment block */ NULL, /* use parent's starting directory */ &startup, /* startup info, i.e. std handles */ &pinfo ); CloseHandle( pipe_write ); if (!ret) { fprintf(stderr, "CreateProcess failure, error %ld\n", GetLastError() ); CloseHandle( pipe_read ); return -1; } CloseHandle( pinfo.hProcess ); CloseHandle( pinfo.hThread ); /* wait for the "OK\n" message */ { char temp[3]; DWORD count; ret = ReadFile( pipe_read, temp, 3, &count, NULL ); CloseHandle( pipe_read ); if ( !ret ) { fprintf(stderr, "could not read ok from ADB Server, error = %ld\n", GetLastError() ); return -1; } if (count != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') { fprintf(stderr, "ADB server didn't ACK\n" ); return -1; } } #elif defined(HAVE_FORKEXEC) char path[PATH_MAX]; int fd[2]; // set up a pipe so the child can tell us when it is ready. // fd[0] will be parent's end, and fd[1] will get mapped to stderr in the child. if (pipe(fd)) { fprintf(stderr, "pipe failed in launch_server, errno: %d\n", errno); return -1; } get_my_path(path, PATH_MAX); pid_t pid = fork(); if(pid < 0) return -1; if (pid == 0) { // child side of the fork // redirect stderr to the pipe // we use stderr instead of stdout due to stdout's buffering behavior. adb_close(fd[0]); dup2(fd[1], STDERR_FILENO); adb_close(fd[1]); char str_port[30]; snprintf(str_port, sizeof(str_port), "%d", server_port); // child process int result = execl(path, "adb", "-P", str_port, "fork-server", "server", NULL); // this should not return fprintf(stderr, "OOPS! execl returned %d, errno: %d\n", result, errno); } else { // parent side of the fork char temp[3]; temp[0] = 'A'; temp[1] = 'B'; temp[2] = 'C'; // wait for the "OK\n" message adb_close(fd[1]); int ret = adb_read(fd[0], temp, 3); int saved_errno = errno; adb_close(fd[0]); if (ret < 0) { fprintf(stderr, "could not read ok from ADB Server, errno = %d\n", saved_errno); return -1; } if (ret != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') { fprintf(stderr, "ADB server didn't ACK\n" ); return -1; } setsid(); } #else #error "cannot implement background server start on this platform" #endif return 0; }
// Build the list of files in the given folder. BOOL BuildFilesInDir_NoHash( _In_ PCWSTR pszFolderpath, _In_opt_ PCHL_QUEUE pqDirsToTraverse, _Inout_ PDIRINFO* ppDirInfo) { SB_ASSERT(pszFolderpath); SB_ASSERT(ppDirInfo); HANDLE hFindFile = NULL; loginfo(L"Building dir: %s", pszFolderpath); if (*ppDirInfo == NULL && FAILED(_Init(pszFolderpath, (pqDirsToTraverse != NULL), ppDirInfo))) { logerr(L"Init failed for dir: %s", pszFolderpath); goto error_return; } // Derefernce just to make it easier to code PDIRINFO pCurDirInfo = *ppDirInfo; // In order to list all files within the specified directory, // path sent to FindFirstFile must end with a "\\*" WCHAR szSearchpath[MAX_PATH] = L""; wcscpy_s(szSearchpath, ARRAYSIZE(szSearchpath), pszFolderpath); int nLen = wcsnlen(pszFolderpath, MAX_PATH); if (nLen > 2 && wcsncmp(pszFolderpath + nLen - 2, L"\\*", MAX_PATH) != 0) { PathCchCombine(szSearchpath, ARRAYSIZE(szSearchpath), pszFolderpath, L"*"); } // Initialize search for files in folder WIN32_FIND_DATA findData; hFindFile = FindFirstFile(szSearchpath, &findData); if (hFindFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_NOT_FOUND) { // No files found under the folder. Just return. return TRUE; } if (hFindFile == INVALID_HANDLE_VALUE) { logerr(L"FindFirstFile()."); goto error_return; } do { // Skip banned files and folders if (IsFileFolderBanned(findData.cFileName, ARRAYSIZE(findData.cFileName))) { continue; } szSearchpath[0] = 0; if (FAILED(PathCchCombine(szSearchpath, ARRAYSIZE(szSearchpath), pszFolderpath, findData.cFileName) == NULL)) { logerr(L"PathCchCombine() failed for %s and %s", pszFolderpath, findData.cFileName); goto error_return; } PFILEINFO pFileInfo; if (!CreateFileInfo(szSearchpath, FALSE, &pFileInfo)) { // Treat as warning and move on. logwarn(L"Unable to get file info for: %s", szSearchpath); continue; } if (pFileInfo->fIsDirectory && pqDirsToTraverse) { // If pqDirsToTraverse is not null, it means caller wants recursive directory traversal PDIRINFO pSubDir; if (FAILED(_Init(szSearchpath, TRUE, &pSubDir))) { logwarn(L"Unable to init dir info for: %s", szSearchpath); free(pFileInfo); continue; } // Insert pSubDir into the queue so that it will be traversed later if (FAILED(pqDirsToTraverse->Insert(pqDirsToTraverse, pSubDir, sizeof pSubDir))) { logwarn(L"Unable to add sub dir [%s] to traversal queue, cur dir: %s", findData.cFileName, pszFolderpath); free(pFileInfo); continue; } ++(pCurDirInfo->nDirs); } else { // Either this is a file or a directory but the folder must be considered as a file // because recursion is not enabled and we want to enable comparison of some attributes of a folder. // If the current file's name is already inserted, then add it to the dup within list BOOL fFileAdded; if (SUCCEEDED(CHL_DsFindHT(pCurDirInfo->phtFiles, findData.cFileName, StringSizeBytes(findData.cFileName), NULL, NULL, TRUE))) { fFileAdded = AddToDupWithinList(&pCurDirInfo->stDupFilesInTree, pFileInfo); } else { fFileAdded = SUCCEEDED(CHL_DsInsertHT(pCurDirInfo->phtFiles, findData.cFileName, StringSizeBytes(findData.cFileName), pFileInfo, sizeof pFileInfo)); } if (!fFileAdded) { logerr(L"Cannot add %s to file list: %s", (pFileInfo->fIsDirectory ? L"dir" : L"file"), findData.cFileName); free(pFileInfo); } else { pFileInfo->fIsDirectory ? ++(pCurDirInfo->nDirs) : ++(pCurDirInfo->nFiles); logdbg(L"Added %s: %s", (pFileInfo->fIsDirectory ? L"dir" : L"file"), findData.cFileName); } } } while (FindNextFile(hFindFile, &findData)); if (GetLastError() != ERROR_NO_MORE_FILES) { logerr(L"Failed in enumerating files in directory: %s", pszFolderpath); goto error_return; } FindClose(hFindFile); return TRUE; error_return: if (hFindFile != INVALID_HANDLE_VALUE) { FindClose(hFindFile); } if (*ppDirInfo != NULL) { DestroyDirInfo_NoHash(*ppDirInfo); *ppDirInfo = NULL; } return FALSE; }
bool MCFileSystemListEntries(const char *p_folder, uint32_t p_options, MCFileSystemListCallback p_callback, void *p_context) { bool t_success; t_success = true; char *t_pattern; t_pattern = nil; if (t_success) t_success = MCCStringFormat(t_pattern, "%s%s", p_folder, MCCStringEndsWith(p_folder, "/") ? "*" : "/*"); void *t_native_pattern; t_native_pattern = nil; if (t_success) t_success = MCFileSystemPathToNative(t_pattern, t_native_pattern); HANDLE t_find_handle; WIN32_FIND_DATAW t_find_data; t_find_handle = INVALID_HANDLE_VALUE; if (t_success) { t_find_handle = FindFirstFileW((LPCWSTR)t_native_pattern, &t_find_data); if (t_find_handle == INVALID_HANDLE_VALUE) t_success = false; } while(t_success) { char *t_entry_filename; if (t_success) t_success = MCFileSystemPathFromNative(t_find_data . cFileName, t_entry_filename); MCFileSystemEntry t_entry; if (t_success) { t_entry . type = (t_find_data . dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0 ? kMCFileSystemEntryFolder : kMCFileSystemEntryFile; MCStringCreateWithCString(t_entry_filename, t_entry.filename); //t_entry . filename = t_entry_filename; t_success = p_callback(p_context, t_entry); } MCCStringFree(t_entry_filename); //// if (!FindNextFileW(t_find_handle, &t_find_data)) { if (GetLastError() == ERROR_NO_MORE_FILES) break; t_success = false; } } if (t_find_handle != INVALID_HANDLE_VALUE) FindClose(t_find_handle); MCMemoryDeallocate(t_native_pattern); MCCStringFree(t_pattern); return t_success; }
void __stdcall serviceMain(DWORD dwArgc, char **lpszArgv) { Logging::LoggerRef logRef(ppg->getLogger(), "WindowsService"); serviceStatusHandle = RegisterServiceCtrlHandler("PaymentGate", serviceHandler); if (serviceStatusHandle == NULL) { logRef(Logging::FATAL, Logging::BRIGHT_RED) << "Couldn't make RegisterServiceCtrlHandler call: " << GetLastErrorMessage(GetLastError()); return; } SERVICE_STATUS serviceStatus{ SERVICE_WIN32_OWN_PROCESS, SERVICE_START_PENDING, 0, NO_ERROR, 0, 1, 3000 }; if (SetServiceStatus(serviceStatusHandle, &serviceStatus) != TRUE) { logRef(Logging::FATAL, Logging::BRIGHT_RED) << "Couldn't make SetServiceStatus call: " << GetLastErrorMessage(GetLastError()); return; } serviceStatus = { SERVICE_WIN32_OWN_PROCESS, SERVICE_RUNNING, SERVICE_ACCEPT_STOP, NO_ERROR, 0, 0, 0 }; if (SetServiceStatus(serviceStatusHandle, &serviceStatus) != TRUE) { logRef(Logging::FATAL, Logging::BRIGHT_RED) << "Couldn't make SetServiceStatus call: " << GetLastErrorMessage(GetLastError()); return; } try { ppg->run(); } catch (std::exception& ex) { logRef(Logging::FATAL, Logging::BRIGHT_RED) << "Error occurred: " << ex.what(); } serviceStatus = { SERVICE_WIN32_OWN_PROCESS, SERVICE_STOPPED, 0, NO_ERROR, 0, 0, 0 }; SetServiceStatus(serviceStatusHandle, &serviceStatus); }
int _tmain(int argc, _TCHAR* argv[]) { dbgtprintf(_T("%d parameter(s)\n"), argc - 1 ); TCHAR command[CMD_BUF_SIZE] = {0}; for(int i = 0; i< argc; i++) { dbgtprintf(_T("%s\n"),argv[i]); } if( argc == 1 ) { _tprintf(_T("Usage:\n")); _tprintf(_T("\t%s <command>\n"), argv[0]); return 0; } else if(argc >= 2) { // Append commands ULONG position = 0; for(int i = 0; i < argc; i++) { if( 0 == i ) { _stprintf_s(command + position, CMD_BUF_SIZE-position-1, _T("%s "), BASE_CMD); position += _tcsnlen(BASE_CMD, CMD_PARAMETER_LENGTH_LIMIT) + 1; } else { _stprintf_s(command + position, CMD_BUF_SIZE-position-1, _T("%s "), argv[i]); position += _tcsnlen(argv[i], CMD_PARAMETER_LENGTH_LIMIT) + 1; } } dbgtprintf(_T("%s\n"),command); } else { _tprintf(_T("Invalid parameter(s)!\n")); return -1; } SECURITY_ATTRIBUTES sa={sizeof ( sa ),NULL,TRUE}; HANDLE hWritePipe = INVALID_HANDLE_VALUE; HANDLE hReadPipe = INVALID_HANDLE_VALUE; BOOL bResult = CreatePipe(&hReadPipe, &hWritePipe, &sa, 0); if ( !bResult || hWritePipe == INVALID_HANDLE_VALUE || hReadPipe == INVALID_HANDLE_VALUE) { _tprintf(TEXT("CreatePipe failed, GLE=%d.\n"), GetLastError()); return -1; } else { dbgtprintf(TEXT("CreatePipe is successful.\n")); } // CreateProcess dbgtprintf(TEXT("Try to CreateProcess.\n")); STARTUPINFO si={0}; si.cb = sizeof(STARTUPINFO); si.dwFlags =STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES; //使用标准柄和显示窗口 si.hStdOutput = hWritePipe;//将文件作为标准输出句柄 si.hStdError = hWritePipe;//将文件作为标准输出句柄 si.wShowWindow = SW_HIDE;//隐藏控制台窗口 PROCESS_INFORMATION pi={0}; PROCESS_WAITING_THREAD_CONTEXT pwi = {0}; pwi.hReadPipe = hReadPipe; pwi.hWritePipe = hWritePipe; if ( CreateProcess ( NULL, command, &sa, &sa, TRUE, NORMAL_PRIORITY_CLASS,NULL,NULL,&si,&pi) ) { pwi.ppi = π dbgtprintf(TEXT("OK to CreateProcess.\n")); HANDLE hThread = CreateThread(&sa, 0, ProcessWaitingThread, &pwi, 0, NULL ); if( 0 != hThread ) { dbgtprintf(TEXT("OK to CreateThread.\n")); SYSTEMTIME st; GetSystemTime(&st); TCHAR logFileName[MAX_PATH] = {0}; _stprintf_s(logFileName, MAX_PATH - 1, _T("RC_%04d%02d%02d-%d-%02d%02d%02d-%03d.log"), st.wYear,st.wMonth,st.wDay,st.wDayOfWeek,st.wHour,st.wMinute,st.wSecond,st.wMilliseconds); dbgtprintf(logFileName); dbgtprintf(L"\n"); HANDLE hLogFile = CreateFile(logFileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, &sa, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if(INVALID_HANDLE_VALUE == hLogFile) { _tprintf(_T("Failed to CreateFile, st = 0x%x\n"), GetLastError()); goto ErrorExit; } else { dbgtprintf(TEXT("OK to CreateFile.\n")); } BOOL bReadable = TRUE; BOOL bWrite = FALSE; while (bReadable) { CHAR strCmdFeedbackBuffer[1024] = {0}; DWORD dwRead = 0; DWORD dwToWrite = 0; DWORD dwWritten = 0; bReadable = ReadFile( hReadPipe, strCmdFeedbackBuffer, 1024-1, &dwRead, NULL); printf(strCmdFeedbackBuffer); dwToWrite = dwRead; bWrite = WriteFile( hLogFile, strCmdFeedbackBuffer, dwToWrite, &dwWritten, NULL); if(!bWrite) { _tprintf(_T("Write to log file error, st=0x%x\n"), GetLastError()); assert(false); } assert(dwToWrite == dwWritten); } CloseHandle(hLogFile); } else { _tprintf(_T("Failed to CreateThread, st = 0x%x\n"), GetLastError()); goto ErrorExit; } } else { _tprintf(_T("Failed to CreateProcess, st = 0x%x\n"), GetLastError()); goto ErrorExit; } // waitThread // goto OkExit; ErrorExit: if (!CloseHandle(hWritePipe)) { _tprintf(_T("Close hWritePipe False, st = 0x%x\n"), GetLastError()); } if (!CloseHandle(hReadPipe)) { _tprintf(_T("Close hWritePipe False, st = 0x%x\n"), GetLastError()); } return -1; OkExit: return 0; }
int unregisterService() { #ifdef WIN32 Logging::LoggerRef logRef(ppg->getLogger(), "ServiceDeregistrator"); SC_HANDLE scManager = NULL; SC_HANDLE scService = NULL; SERVICE_STATUS ssSvcStatus = { }; int ret = 0; for (;;) { scManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); if (scManager == NULL) { logRef(Logging::FATAL, Logging::BRIGHT_RED) << "OpenSCManager failed with error: " << GetLastErrorMessage(GetLastError()); ret = 1; break; } scService = OpenService(scManager, SERVICE_NAME, SERVICE_STOP | SERVICE_QUERY_STATUS | DELETE); if (scService == NULL) { logRef(Logging::FATAL, Logging::BRIGHT_RED) << "OpenService failed with error: " << GetLastErrorMessage(GetLastError()); ret = 1; break; } if (ControlService(scService, SERVICE_CONTROL_STOP, &ssSvcStatus)) { logRef(Logging::INFO) << "Stopping " << SERVICE_NAME; Sleep(1000); while (QueryServiceStatus(scService, &ssSvcStatus)) { if (ssSvcStatus.dwCurrentState == SERVICE_STOP_PENDING) { logRef(Logging::INFO) << "Waiting..."; Sleep(1000); } else { break; } } std::cout << std::endl; if (ssSvcStatus.dwCurrentState == SERVICE_STOPPED) { logRef(Logging::INFO) << SERVICE_NAME << " is stopped"; } else { logRef(Logging::FATAL, Logging::BRIGHT_RED) << SERVICE_NAME << " failed to stop" << std::endl; } } if (!DeleteService(scService)) { logRef(Logging::FATAL, Logging::BRIGHT_RED) << "DeleteService failed with error: " << GetLastErrorMessage(GetLastError()); ret = 1; break; } logRef(Logging::INFO) << SERVICE_NAME << " is removed"; break; } if (scManager) { CloseServiceHandle(scManager); } if (scService) { CloseServiceHandle(scService); } return ret; #else return 0; #endif }
int registerService() { #ifdef WIN32 Logging::LoggerRef logRef(ppg->getLogger(), "ServiceRegistrator"); char pathBuff[MAX_PATH]; std::string modulePath; SC_HANDLE scManager = NULL; SC_HANDLE scService = NULL; int ret = 0; for (;;) { if (GetModuleFileName(NULL, pathBuff, ARRAYSIZE(pathBuff)) == 0) { logRef(Logging::FATAL, Logging::BRIGHT_RED) << "GetModuleFileName failed with error: " << GetLastErrorMessage(GetLastError()); ret = 1; break; } modulePath.assign(pathBuff); std::string moduleDir = modulePath.substr(0, modulePath.find_last_of('\\') + 1); modulePath += " --config=" + moduleDir + "payment_service.conf -d"; scManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT | SC_MANAGER_CREATE_SERVICE); if (scManager == NULL) { logRef(Logging::FATAL, Logging::BRIGHT_RED) << "OpenSCManager failed with error: " << GetLastErrorMessage(GetLastError()); ret = 1; break; } scService = CreateService(scManager, SERVICE_NAME, NULL, SERVICE_QUERY_STATUS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, modulePath.c_str(), NULL, NULL, NULL, NULL, NULL); if (scService == NULL) { logRef(Logging::FATAL, Logging::BRIGHT_RED) << "CreateService failed with error: " << GetLastErrorMessage(GetLastError()); ret = 1; break; } logRef(Logging::INFO) << "Service is registered successfully"; logRef(Logging::INFO) << "Please make sure " << moduleDir + "payment_service.conf" << " exists"; break; } if (scManager) { CloseServiceHandle(scManager); } if (scService) { CloseServiceHandle(scService); } return ret; #else return 0; #endif }
int runDaemon() { #ifdef WIN32 SERVICE_TABLE_ENTRY serviceTable[] { { "Payment Gate", serviceMain }, { NULL, NULL } }; Logging::LoggerRef logRef(ppg->getLogger(), "RunService"); if (StartServiceCtrlDispatcher(serviceTable) != TRUE) { logRef(Logging::FATAL, Logging::BRIGHT_RED) << "Couldn't start service: " << GetLastErrorMessage(GetLastError()); return 1; } logRef(Logging::INFO) << "Service stopped"; return 0; #else int daemonResult = daemonize(); if (daemonResult > 0) { //parent return 0; } else if (daemonResult < 0) { //error occurred return 1; } ppg->run(); return 0; #endif }
static void test_AddRemoveProvider(void) { BOOL ret; SIP_ADD_NEWPROVIDER newprov; GUID actionid = { 0xdeadbe, 0xefde, 0xadbe, { 0xef,0xde,0xad,0xbe,0xef,0xde,0xad,0xbe }}; static WCHAR dummydll[] = {'d','e','a','d','b','e','e','f','.','d','l','l',0 }; static WCHAR dummyfunction[] = {'d','u','m','m','y','f','u','n','c','t','i','o','n',0 }; /* NULL check */ SetLastError(0xdeadbeef); ret = CryptSIPRemoveProvider(NULL); ok (!ret, "Expected CryptSIPRemoveProvider to fail.\n"); ok (GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d.\n", GetLastError()); /* nonexistent provider should result in a registry error */ SetLastError(0xdeadbeef); ret = CryptSIPRemoveProvider(&actionid); if (!ret && GetLastError() == ERROR_ACCESS_DENIED) { /* Apparently the needed rights are checked before the existence of the provider */ skip("Need admin rights\n"); } else { /* On some Win98 systems, CryptSIPRemoveProvider always succeeds if * the arguments are correct, whether or not the registry key is * present, so don't test ret, just check the last error if it does * return FALSE. */ if (!ret) ok (GetLastError() == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d.\n", GetLastError()); } /* Everything OK, pwszIsFunctionName and pwszIsFunctionNameFmt2 are left NULL * as allowed */ memset(&newprov, 0, sizeof(SIP_ADD_NEWPROVIDER)); newprov.cbStruct = sizeof(SIP_ADD_NEWPROVIDER); newprov.pgSubject = &actionid; newprov.pwszDLLFileName = dummydll; newprov.pwszGetFuncName = dummyfunction; newprov.pwszPutFuncName = dummyfunction; newprov.pwszCreateFuncName = dummyfunction; newprov.pwszVerifyFuncName = dummyfunction; newprov.pwszRemoveFuncName = dummyfunction; SetLastError(0xdeadbeef); ret = CryptSIPAddProvider(&newprov); if (!ret && GetLastError() == ERROR_ACCESS_DENIED) { skip("Need admin rights\n"); return; } ok ( ret, "CryptSIPAddProvider should have succeeded, last error %d\n", GetLastError()); /* Dummy provider will be deleted, but the function still fails because * pwszIsFunctionName and pwszIsFunctionNameFmt2 are not present in the * registry. */ SetLastError(0xdeadbeef); ret = CryptSIPRemoveProvider(&actionid); /* On some Win98 systems, CryptSIPRemoveProvider always succeeds if * the arguments are correct, whether or not the registry key is * present, so don't test ret, just check the last error if it does * return FALSE. */ if (!ret) ok (GetLastError() == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d.\n", GetLastError()); /* Everything OK */ memset(&newprov, 0, sizeof(SIP_ADD_NEWPROVIDER)); newprov.cbStruct = sizeof(SIP_ADD_NEWPROVIDER); newprov.pgSubject = &actionid; newprov.pwszDLLFileName = dummydll; newprov.pwszGetFuncName = dummyfunction; newprov.pwszPutFuncName = dummyfunction; newprov.pwszCreateFuncName = dummyfunction; newprov.pwszVerifyFuncName = dummyfunction; newprov.pwszRemoveFuncName = dummyfunction; newprov.pwszIsFunctionNameFmt2 = dummyfunction; newprov.pwszIsFunctionName = dummyfunction; /* If GetCapFuncName set to NULL, then CryptSIPRemoveProvider fails on win 8 */ newprov.pwszGetCapFuncName = dummyfunction; SetLastError(0xdeadbeef); ret = CryptSIPAddProvider(&newprov); ok ( ret, "CryptSIPAddProvider should have succeeded, last error %d\n", GetLastError()); /* Dummy provider should be deleted */ SetLastError(0xdeadbeef); ret = CryptSIPRemoveProvider(&actionid); ok ( ret, "CryptSIPRemoveProvider should have succeeded, last error %d\n", GetLastError()); }
TBOOL File::MoveFile(const string& strSrcFileName,const string& strDestFileName) { //extern int errno; if(File::FileExist(strDestFileName)==TRUE) { if(File::RemoveFile(strDestFileName)==FALSE) { printf("RemoveFile %s failed\n",(LPCSTR)strDestFileName.c_str()) ; } } #ifndef WIN32 int nResult=rename(strSrcFileName.c_str(),strDestFileName.c_str()); if(nResult==0) return(TRUE); else if(errno==18) { if(CopyFile(strSrcFileName,strDestFileName)==FALSE) return(FALSE); else { FileStatus fstatus; File::GetStatus(strSrcFileName.c_str(),fstatus); struct utimbuf ut; ut.actime=fstatus.m_atime.getTime(); ut.modtime=fstatus.m_mtime.getTime(); utime((LPCSTR)strDestFileName.c_str(),&ut); // 增加文件日期复制 File::RemoveFile(strSrcFileName); return(TRUE); } } else { #ifdef _DEBUG LOG_ERROR(("Move File %s to %s failed(errno=%d,%s)\n", strSrcFileName, strDestFileName, errno, strerror(errno))); #endif return(FALSE); } #else TBOOL bResult=::MoveFileA(strSrcFileName.c_str(),strDestFileName.c_str()); if(bResult==FALSE) { #ifdef _DEBUG //char lpMsgBuf[1024] ; LPVOID lpMsgBuf; WORD err = GetLastError() ; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), 0, // Default language (LPTSTR) &lpMsgBuf, 0, NULL ); BASE_LOG_ERROR("Move File %s to %s failed(errno=%d,%s)\n", strSrcFileName.c_str(), strDestFileName.c_str(), err, (char*)lpMsgBuf); LocalFree( lpMsgBuf ); #endif return(FALSE); } else return(TRUE); #endif }
Handle timing_dispatch_c(TaskData *taskData, Handle args, Handle code) { unsigned c = get_C_unsigned(taskData, DEREFWORDHANDLE(code)); switch (c) { case 0: /* Get ticks per microsecond. */ return Make_arbitrary_precision(taskData, TICKS_PER_MICROSECOND); case 1: /* Return time since the time base. */ { #if (defined(_WIN32) && ! defined(__CYGWIN__)) FILETIME ft; GetSystemTimeAsFileTime(&ft); return Make_arb_from_Filetime(taskData, ft); #else struct timeval tv; if (gettimeofday(&tv, NULL) != 0) raise_syscall(taskData, "gettimeofday failed", errno); return Make_arb_from_pair_scaled(taskData, tv.tv_sec, tv.tv_usec, 1000000); #endif } case 2: /* Return the base year. This is the year which corresponds to zero in the timing sequence. */ #if (defined(_WIN32) && ! defined(__CYGWIN__)) return Make_arbitrary_precision(taskData, 1601); #else return Make_arbitrary_precision(taskData, 1970); #endif case 3: /* In both Windows and Unix the time base is 1st of January in the base year. This function is provided just in case we are running on a system with a different base. It returns the number of seconds after 1st January of the base year that corresponds to zero of the time base. */ return Make_arbitrary_precision(taskData, 0); case 4: /* Return the time offset which applied/will apply at the specified time (in seconds). */ { int localoff = 0; time_t theTime; int day = 0; #if (defined(HAVE_GMTIME_R) || defined(HAVE_LOCALTIME_R)) struct tm result; #endif #if (defined(_WIN32) && ! defined(__CYGWIN__)) /* Although the offset is in seconds it is since 1601. */ FILETIME ftSeconds; // Not really a file-time because it's a number of seconds. getFileTimeFromArb(taskData, args, &ftSeconds); /* May raise exception. */ ULARGE_INTEGER liTime; liTime.HighPart = ftSeconds.dwHighDateTime; liTime.LowPart = ftSeconds.dwLowDateTime; theTime = (long)(liTime.QuadPart - SECSSINCE1601); #else theTime = get_C_long(taskData, DEREFWORDHANDLE(args)); /* May raise exception. */ #endif { #ifdef HAVE_GMTIME_R struct tm *loctime = gmtime_r(&theTime, &result); #else PLocker lock(&timeLock); struct tm *loctime = gmtime(&theTime); #endif if (loctime == NULL) raise_exception0(taskData, EXC_size); localoff = (loctime->tm_hour*60 + loctime->tm_min)*60 + loctime->tm_sec; day = loctime->tm_yday; } { #ifdef HAVE_LOCALTIME_R struct tm *loctime = localtime_r(&theTime, &result); #else PLocker lock(&timeLock); struct tm *loctime = localtime(&theTime); #endif if (loctime == NULL) raise_exception0(taskData, EXC_size); localoff -= (loctime->tm_hour*60 + loctime->tm_min)*60 + loctime->tm_sec; if (loctime->tm_yday != day) { // Different day - have to correct it. We can assume that there // is at most one day to correct. if (day == loctime->tm_yday+1 || (day == 0 && loctime->tm_yday >= 364)) localoff += 24*60*60; else localoff -= 24*60*60; } } return Make_arbitrary_precision(taskData, localoff); } case 5: /* Find out if Summer Time (daylight saving) was/will be in effect. */ { time_t theTime; #if (defined(_WIN32) && ! defined(__CYGWIN__)) FILETIME ftSeconds; // Not really a file-time because it's a number of seconds. getFileTimeFromArb(taskData, args, &ftSeconds); /* May raise exception. */ ULARGE_INTEGER liTime; liTime.HighPart = ftSeconds.dwHighDateTime; liTime.LowPart = ftSeconds.dwLowDateTime; theTime = (long)(liTime.QuadPart - SECSSINCE1601); #else theTime = get_C_long(taskData, DEREFWORDHANDLE(args)); /* May raise exception. */ #endif int isDst = 0; #ifdef HAVE_LOCALTIME_R struct tm result; struct tm *loctime = localtime_r(&theTime, &result); isDst = loctime->tm_isdst; #else { PLocker lock(&timeLock); struct tm *loctime = localtime(&theTime); if (loctime == NULL) raise_exception0(taskData, EXC_size); isDst = loctime->tm_isdst; } #endif return Make_arbitrary_precision(taskData, isDst); } case 6: /* Call strftime. It would be possible to do much of this in ML except that it requires the current locale. */ { struct tm time; char *format, buff[2048]; Handle resString; /* Get the format string. */ format = Poly_string_to_C_alloc(DEREFHANDLE(args)->Get(0)); /* Copy the time information. */ time.tm_year = get_C_int(taskData, DEREFHANDLE(args)->Get(1)) - 1900; time.tm_mon = get_C_int(taskData, DEREFHANDLE(args)->Get(2)); time.tm_mday = get_C_int(taskData, DEREFHANDLE(args)->Get(3)); time.tm_hour = get_C_int(taskData, DEREFHANDLE(args)->Get(4)); time.tm_min = get_C_int(taskData, DEREFHANDLE(args)->Get(5)); time.tm_sec = get_C_int(taskData, DEREFHANDLE(args)->Get(6)); time.tm_wday = get_C_int(taskData, DEREFHANDLE(args)->Get(7)); time.tm_yday = get_C_int(taskData, DEREFHANDLE(args)->Get(8)); time.tm_isdst = get_C_int(taskData, DEREFHANDLE(args)->Get(9)); #if (defined(_WIN32) && ! defined(__CYGWIN__)) _tzset(); /* Make sure we set the current locale. */ #else setlocale(LC_TIME, ""); #endif /* It would be better to dynamically allocate the string rather than use a fixed size but Unix unlike Windows does not distinguish between an error in the input and the buffer being too small. */ if (strftime(buff, sizeof(buff), format, &time) <= 0) { /* Error */ free(format); raise_exception0(taskData, EXC_size); } resString = taskData->saveVec.push(C_string_to_Poly(taskData, buff)); free(format); return resString; } case 7: /* Return User CPU time since the start. */ { #if (defined(_WIN32) && ! defined(__CYGWIN__)) FILETIME ut, ct, et, kt; if (! GetProcessTimes(GetCurrentProcess(), &ct, &et, &kt, &ut)) raise_syscall(taskData, "GetProcessTimes failed", 0-GetLastError()); return Make_arb_from_Filetime(taskData, ut); #else struct rusage rusage; if (getrusage(RUSAGE_SELF, &rusage) != 0) raise_syscall(taskData, "getrusage failed", errno); return Make_arb_from_pair_scaled(taskData, rusage.ru_utime.tv_sec, rusage.ru_utime.tv_usec, 1000000); #endif } case 8: /* Return System CPU time since the start. */ { #if (defined(_WIN32) && ! defined(__CYGWIN__)) FILETIME ct, et, kt, ut; if (! GetProcessTimes(GetCurrentProcess(), &ct, &et, &kt, &ut)) raise_syscall(taskData, "GetProcessTimes failed", 0-GetLastError()); return Make_arb_from_Filetime(taskData, kt); #else struct rusage rusage; if (getrusage(RUSAGE_SELF, &rusage) != 0) raise_syscall(taskData, "getrusage failed", errno); return Make_arb_from_pair_scaled(taskData, rusage.ru_stime.tv_sec, rusage.ru_stime.tv_usec, 1000000); #endif } case 9: /* Return GC time since the start. */ return gHeapSizeParameters.getGCUtime(taskData); case 10: /* Return real time since the start. */ { #if (defined(_WIN32) && ! defined(__CYGWIN__)) FILETIME ft; GetSystemTimeAsFileTime(&ft); subFiletimes(&ft, &startTime); return Make_arb_from_Filetime(taskData, ft); #else struct timeval tv; if (gettimeofday(&tv, NULL) != 0) raise_syscall(taskData, "gettimeofday failed", errno); subTimevals(&tv, &startTime); return Make_arb_from_pair_scaled(taskData, tv.tv_sec, tv.tv_usec, 1000000); #endif } /* These next two are used only in the Posix structure. */ case 11: /* Return User CPU time used by child processes. */ { #if (defined(_WIN32) && ! defined(__CYGWIN__)) return Make_arbitrary_precision(taskData, 0); #else struct rusage rusage; if (getrusage(RUSAGE_CHILDREN, &rusage) != 0) raise_syscall(taskData, "getrusage failed", errno); return Make_arb_from_pair_scaled(taskData, rusage.ru_utime.tv_sec, rusage.ru_utime.tv_usec, 1000000); #endif } case 12: /* Return System CPU time used by child processes. */ { #if (defined(_WIN32) && ! defined(__CYGWIN__)) return Make_arbitrary_precision(taskData, 0); #else struct rusage rusage; if (getrusage(RUSAGE_CHILDREN, &rusage) != 0) raise_syscall(taskData, "getrusage failed", errno); return Make_arb_from_pair_scaled(taskData, rusage.ru_stime.tv_sec, rusage.ru_stime.tv_usec, 1000000); #endif } case 13: /* Return GC system time since the start. */ return gHeapSizeParameters.getGCStime(taskData); default: { char msg[100]; sprintf(msg, "Unknown timing function: %d", c); raise_exception_string(taskData, EXC_Fail, msg); return 0; } } }
SharedPortEndpoint::~SharedPortEndpoint() { StopListener(); #ifdef WIN32 if(wake_select_source) { delete wake_select_source; delete wake_select_dest; } if( thread_killed != INVALID_HANDLE_VALUE ) { DWORD wait_result = WaitForSingleObject(thread_killed, 100); if(wait_result != WAIT_OBJECT_0) dprintf(D_ALWAYS, "SharedPortEndpoint: Destructor: Problem in thread shutdown notification: %d\n", GetLastError()); CloseHandle(thread_killed); } #endif }
bool WINAPI SFileCompactArchive(HANDLE hMpq, const char * szListFile, bool /* bReserved */) { TFileStream * pTempStream = NULL; TMPQArchive * ha = (TMPQArchive *)hMpq; ULONGLONG ByteOffset; ULONGLONG ByteCount; LPDWORD pFileKeys = NULL; TCHAR szTempFile[MAX_PATH] = _T(""); TCHAR * szTemp = NULL; int nError = ERROR_SUCCESS; // Test the valid parameters if(!IsValidMpqHandle(ha)) nError = ERROR_INVALID_HANDLE; if(ha->dwFlags & MPQ_FLAG_READ_ONLY) nError = ERROR_ACCESS_DENIED; // If the MPQ is changed at this moment, we have to flush the archive if(nError == ERROR_SUCCESS && (ha->dwFlags & MPQ_FLAG_CHANGED)) { SFileFlushArchive(hMpq); } // Create the table with file keys if(nError == ERROR_SUCCESS) { if((pFileKeys = STORM_ALLOC(DWORD, ha->dwFileTableSize)) != NULL) memset(pFileKeys, 0, sizeof(DWORD) * ha->dwFileTableSize); else nError = ERROR_NOT_ENOUGH_MEMORY; } // First of all, we have to check of we are able to decrypt all files. // If not, sorry, but the archive cannot be compacted. if(nError == ERROR_SUCCESS) { // Initialize the progress variables for compact callback FileStream_GetSize(ha->pStream, CompactTotalBytes); CompactBytesProcessed = 0; nError = CheckIfAllFilesKnown(ha, szListFile, pFileKeys); } // Get the temporary file name and create it if(nError == ERROR_SUCCESS) { _tcscpy(szTempFile, ha->pStream->szFileName); if((szTemp = _tcsrchr(szTempFile, '.')) != NULL) _tcscpy(szTemp + 1, _T("mp_")); else _tcscat(szTempFile, _T("_")); pTempStream = FileStream_CreateFile(szTempFile); if(pTempStream == NULL) nError = GetLastError(); } // Write the data before MPQ user data (if any) if(nError == ERROR_SUCCESS && ha->UserDataPos != 0) { // Inform the application about the progress if(CompactCB != NULL) CompactCB(pvUserData, CCB_COPYING_NON_MPQ_DATA, CompactBytesProcessed, CompactTotalBytes); ByteOffset = 0; ByteCount = ha->UserDataPos; nError = CopyNonMpqData(ha->pStream, pTempStream, ByteOffset, ByteCount); } // Write the MPQ user data (if any) if(nError == ERROR_SUCCESS && ha->MpqPos > ha->UserDataPos) { // At this point, we assume that the user data size is equal // to pUserData->dwHeaderOffs. // If this assumption doesn't work, then we have an unknown version of MPQ ByteOffset = ha->UserDataPos; ByteCount = ha->MpqPos - ha->UserDataPos; assert(ha->pUserData != NULL); assert(ha->pUserData->dwHeaderOffs == ByteCount); nError = CopyNonMpqData(ha->pStream, pTempStream, ByteOffset, ByteCount); } // Write the MPQ header if(nError == ERROR_SUCCESS) { // Remember the header size before swapping DWORD dwBytesToWrite = ha->pHeader->dwHeaderSize; BSWAP_TMPQHEADER(ha->pHeader); if(!FileStream_Write(pTempStream, NULL, ha->pHeader, dwBytesToWrite)) nError = GetLastError(); BSWAP_TMPQHEADER(ha->pHeader); // Update the progress CompactBytesProcessed += ha->pHeader->dwHeaderSize; } // Now copy all files if(nError == ERROR_SUCCESS) { nError = CopyMpqFiles(ha, pFileKeys, pTempStream); ha->dwFlags |= MPQ_FLAG_CHANGED; } // If succeeded, switch the streams if(nError == ERROR_SUCCESS) { if(FileStream_MoveFile(ha->pStream, pTempStream)) pTempStream = NULL; else nError = ERROR_CAN_NOT_COMPLETE; } // If all succeeded, save the MPQ tables if(nError == ERROR_SUCCESS) { // // Note: We don't recalculate position of the MPQ tables at this point. // SaveMPQTables does it automatically. // nError = SaveMPQTables(ha); if(nError == ERROR_SUCCESS && CompactCB != NULL) { CompactBytesProcessed += (ha->pHeader->dwHashTableSize * sizeof(TMPQHash)); CompactBytesProcessed += (ha->pHeader->dwBlockTableSize * sizeof(TMPQBlock)); CompactCB(pvUserData, CCB_CLOSING_ARCHIVE, CompactBytesProcessed, CompactTotalBytes); } } // Invalidate the compact callback pvUserData = NULL; CompactCB = NULL; // Cleanup and return if(pTempStream != NULL) FileStream_Close(pTempStream); if(pFileKeys != NULL) STORM_FREE(pFileKeys); if(nError != ERROR_SUCCESS) SetLastError(nError); return (nError == ERROR_SUCCESS); }
void SharedPortEndpoint::StopListener() { #ifdef WIN32 /* On Windows we only need to close the pipe ends for the two pipes we're using. */ dprintf(D_FULLDEBUG, "SharedPortEndpoint: Inside stop listener.\n"); if( m_registered_listener ) { bool tried = false; HANDLE child_pipe; EnterCriticalSection(&kill_lock); kill_thread = true; LeaveCriticalSection(&kill_lock); while(true) { if(tried) { dprintf(D_ALWAYS, "ERROR: SharedPortEndpoint: Failed to cleanly terminate pipe listener\n"); MSC_SUPPRESS_WARNING_FOREVER(6258) // warning: Using TerminateThread does not allow proper thread clean up TerminateThread(thread_handle, 0); break; } child_pipe = CreateFile( m_full_name.Value(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if(child_pipe == INVALID_HANDLE_VALUE) { dprintf(D_ALWAYS, "ERROR: SharedPortEndpoint: Named pipe does not exist.\n"); MSC_SUPPRESS_WARNING_FOREVER(6258) // warning: Using TerminateThread does not allow proper thread clean up TerminateThread(thread_handle, 0); break; } if(GetLastError() == ERROR_PIPE_BUSY) { if (!WaitNamedPipe(m_full_name.Value(), 20000)) { dprintf(D_ALWAYS, "ERROR: SharedPortEndpoint: Wait for named pipe for sending socket timed out: %d\n", GetLastError()); MSC_SUPPRESS_WARNING_FOREVER(6258) // warning: Using TerminateThread does not allow proper thread clean up TerminateThread(thread_handle, 0); break; } tried = true; continue; } CloseHandle(child_pipe); break; } CloseHandle(thread_handle); DeleteCriticalSection(&received_lock); } #else if( m_registered_listener && daemonCore ) { daemonCore->Cancel_Socket( &m_listener_sock ); } m_listener_sock.close(); if( !m_full_name.IsEmpty() ) { RemoveSocket(m_full_name.Value()); } if( m_retry_remote_addr_timer != -1 ) { daemonCore->Cancel_Timer( m_retry_remote_addr_timer ); m_retry_remote_addr_timer = -1; } #endif m_listening = false; m_registered_listener = false; m_remote_addr = ""; }
LONG MiniDumper::TopLevelFilter( struct _EXCEPTION_POINTERS *pExceptionInfo ) { LONG retval = EXCEPTION_CONTINUE_SEARCH; // firstly see if dbghelp.dll is around and has the function we need // look next to the EXE first, as the one in System32 might be old // (e.g. Windows 2000) HMODULE hDll = nullptr; TCHAR szDbgHelpPath[_MAX_PATH]; if (GetModuleFileName( NULL, szDbgHelpPath, _MAX_PATH )) { tstring folder = GetFolderNameFromFullFileName(szDbgHelpPath); folder += TEXT("dbghelp.dll"); hDll = ::LoadLibrary( folder.c_str() ); } if (hDll == nullptr) { // load any version we can hDll = ::LoadLibrary( TEXT("DBGHELP.DLL") ); } LPCTSTR szResult = nullptr; if (hDll) { MINIDUMPWRITEDUMP pDump = (MINIDUMPWRITEDUMP)::GetProcAddress( hDll, "MiniDumpWriteDump" ); if (pDump) { TCHAR szDumpPath[_MAX_PATH]; TCHAR szScratch [_MAX_PATH]; SPrintf( szDumpPath, _MAX_PATH, TEXT("%s"), pThis->m_szDumpFilename); // ask the user if they want to save a dump file //if (::MessageBox( NULL, "Something bad happened in your program, would you like to save a diagnostic file?", m_szAppName, MB_YESNO )==IDYES) { // create the file HANDLE hFile = ::CreateFile( szDumpPath, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); if (hFile!=INVALID_HANDLE_VALUE) { _MINIDUMP_EXCEPTION_INFORMATION ExInfo; ExInfo.ThreadId = ::GetCurrentThreadId(); ExInfo.ExceptionPointers = pExceptionInfo; ExInfo.ClientPointers = NULL; // write the dump BOOL bOK = pDump( GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &ExInfo, NULL, NULL ); ::CloseHandle(hFile); if (bOK) { TCHAR szErrorReason[256]; SPrintf(szErrorReason, 256, TEXT("ZViewer Error : %s"), GetFaultReason(pExceptionInfo).c_str()); MessageBox(HWND_DESKTOP, szErrorReason, TEXT("ZViewer"), MB_OK); MessageBox(HWND_DESKTOP, pThis->m_szDumpMsg, TEXT("ZViewer"), MB_OK); SPrintf( szScratch, _MAX_PATH, TEXT("Saved dump file to '%s'"), szDumpPath ); szResult = szScratch; retval = EXCEPTION_EXECUTE_HANDLER; } else { SPrintf( szScratch, _MAX_PATH, TEXT("Failed to save dump file to '%s' (error %u)"), szDumpPath, GetLastError() ); szResult = szScratch; } } else { SPrintf( szScratch, _MAX_PATH, TEXT("Failed to create dump file '%s' (error %u)"), szDumpPath, GetLastError() ); szResult = szScratch; } } } else { szResult = TEXT("DBGHELP.DLL too old"); } } else { szResult = TEXT("DBGHELP.DLL not found"); } return retval; }
bool SharedPortEndpoint::CreateListener() { #ifndef HAVE_SHARED_PORT return false; #elif WIN32 if( m_listening ) { dprintf(D_ALWAYS, "SharedPortEndpoint: listener already created.\n"); return true; } m_full_name.formatstr("%s%c%s", m_socket_dir.c_str(), DIR_DELIM_CHAR, m_local_id.c_str()); pipe_end = CreateNamedPipe( m_full_name.Value(), PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, 1, 1024, 1024, 0, NULL); if(pipe_end == INVALID_HANDLE_VALUE) { DWORD error = GetLastError(); EXCEPT("SharedPortEndpoint: Failed to create named pipe: %d", error); } #elif HAVE_SCM_RIGHTS_PASSFD if( m_listening ) { return true; } int sock_fd = socket(AF_UNIX,SOCK_STREAM,0); if( sock_fd == -1 ) { dprintf(D_ALWAYS, "ERROR: SharedPortEndpoint: failed to open listener socket: %s\n", strerror(errno)); return false; } m_listener_sock.close(); m_listener_sock.assignDomainSocket( sock_fd ); m_full_name.formatstr("%s%c%s", m_socket_dir.c_str(), DIR_DELIM_CHAR, m_local_id.c_str()); struct sockaddr_un named_sock_addr; memset(&named_sock_addr, 0, sizeof(named_sock_addr)); named_sock_addr.sun_family = AF_UNIX; unsigned named_sock_addr_len; bool is_no_good; if (m_is_file_socket) { strncpy(named_sock_addr.sun_path, m_full_name.Value(), sizeof(named_sock_addr.sun_path)-1); named_sock_addr_len = SUN_LEN(&named_sock_addr); is_no_good = strcmp(named_sock_addr.sun_path,m_full_name.Value()); } else { strncpy(named_sock_addr.sun_path+1, m_full_name.Value(), sizeof(named_sock_addr.sun_path)-2); named_sock_addr_len = sizeof(named_sock_addr) - sizeof(named_sock_addr.sun_path) + 1 + strlen(named_sock_addr.sun_path+1); is_no_good = strcmp(named_sock_addr.sun_path+1,m_full_name.Value());; } if( is_no_good ) { dprintf(D_ALWAYS, "ERROR: SharedPortEndpoint: full listener socket name is too long." " Consider changing DAEMON_SOCKET_DIR to avoid this:" " %s\n",m_full_name.Value()); return false; } while( true ) { priv_state orig_priv = get_priv(); bool tried_priv_switch = false; if( orig_priv == PRIV_USER ) { set_condor_priv(); tried_priv_switch = true; } int bind_rc = bind( sock_fd, (struct sockaddr *)&named_sock_addr, named_sock_addr_len); if( tried_priv_switch ) { set_priv( orig_priv ); } if( bind_rc == 0 ) { break; } int bind_errno = errno; // bind failed: deal with some common sources of error if( m_is_file_socket && RemoveSocket(m_full_name.Value()) ) { dprintf(D_ALWAYS, "WARNING: SharedPortEndpoint: removing pre-existing socket %s\n", m_full_name.Value()); continue; } else if( m_is_file_socket && MakeDaemonSocketDir() ) { dprintf(D_ALWAYS, "SharedPortEndpoint: creating DAEMON_SOCKET_DIR=%s\n", m_socket_dir.Value()); continue; } dprintf(D_ALWAYS, "ERROR: SharedPortEndpoint: failed to bind to %s: %s\n", m_full_name.Value(), strerror(bind_errno)); return false; } if( listen( sock_fd, param_integer( "SOCKET_LISTEN_BACKLOG", 500 ) ) ) { dprintf(D_ALWAYS, "ERROR: SharedPortEndpoint: failed to listen on %s: %s\n", m_full_name.Value(), strerror(errno)); return false; } m_listener_sock._state = Sock::sock_special; m_listener_sock._special_state = ReliSock::relisock_listen; #else #error HAVE_SHARED_PORT is defined, but no method for passing fds is enabled. #endif m_listening = true; return true; }
CURLcode Curl_telnet(struct connectdata *conn) { CURLcode code; struct SessionHandle *data = conn->data; curl_socket_t sockfd = conn->sock[FIRSTSOCKET]; #ifdef WIN32 HMODULE wsock2; WSOCK2_FUNC close_event_func; WSOCK2_FUNC create_event_func; WSOCK2_FUNC event_select_func; WSOCK2_FUNC enum_netevents_func; WSAEVENT event_handle; WSANETWORKEVENTS events; HANDLE stdin_handle; HANDLE objs[2]; DWORD waitret; DWORD readfile_read; #else fd_set readfd; fd_set keepfd; #endif ssize_t nread; bool keepon = TRUE; char *buf = data->state.buffer; struct TELNET *tn; code = init_telnet(conn); if(code) return code; tn = (struct TELNET *)conn->proto.telnet; code = check_telnet_options(conn); if(code) return code; #ifdef WIN32 /* ** This functionality only works with WinSock >= 2.0. So, ** make sure have it. */ code = check_wsock2(data); if (code) return code; /* OK, so we have WinSock 2.0. We need to dynamically */ /* load ws2_32.dll and get the function pointers we need. */ wsock2 = LoadLibrary("WS2_32.DLL"); if (wsock2 == NULL) { failf(data,"failed to load WS2_32.DLL (%d)",GetLastError()); return CURLE_FAILED_INIT; } /* Grab a pointer to WSACreateEvent */ create_event_func = GetProcAddress(wsock2,"WSACreateEvent"); if (create_event_func == NULL) { failf(data,"failed to find WSACreateEvent function (%d)", GetLastError()); FreeLibrary(wsock2); return CURLE_FAILED_INIT; } /* And WSACloseEvent */ close_event_func = GetProcAddress(wsock2,"WSACloseEvent"); if (create_event_func == NULL) { failf(data,"failed to find WSACloseEvent function (%d)", GetLastError()); FreeLibrary(wsock2); return CURLE_FAILED_INIT; } /* And WSAEventSelect */ event_select_func = GetProcAddress(wsock2,"WSAEventSelect"); if (event_select_func == NULL) { failf(data,"failed to find WSAEventSelect function (%d)", GetLastError()); FreeLibrary(wsock2); return CURLE_FAILED_INIT; } /* And WSAEnumNetworkEvents */ enum_netevents_func = GetProcAddress(wsock2,"WSAEnumNetworkEvents"); if (enum_netevents_func == NULL) { failf(data,"failed to find WSAEnumNetworkEvents function (%d)", GetLastError()); FreeLibrary(wsock2); return CURLE_FAILED_INIT; } /* We want to wait for both stdin and the socket. Since ** the select() function in winsock only works on sockets ** we have to use the WaitForMultipleObjects() call. */ /* First, create a sockets event object */ event_handle = (WSAEVENT)create_event_func(); if (event_handle == WSA_INVALID_EVENT) { failf(data,"WSACreateEvent failed (%d)",WSAGetLastError()); FreeLibrary(wsock2); return CURLE_FAILED_INIT; } /* The get the Windows file handle for stdin */ stdin_handle = GetStdHandle(STD_INPUT_HANDLE); /* Create the list of objects to wait for */ objs[0] = stdin_handle; objs[1] = event_handle; /* Tell winsock what events we want to listen to */ if(event_select_func(sockfd, event_handle, FD_READ|FD_CLOSE) == SOCKET_ERROR) { close_event_func(event_handle); FreeLibrary(wsock2); return 0; } /* Keep on listening and act on events */ while(keepon) { waitret = WaitForMultipleObjects(2, objs, FALSE, INFINITE); switch(waitret - WAIT_OBJECT_0) { case 0: { unsigned char outbuf[2]; int out_count = 0; ssize_t bytes_written; char *buffer = buf; if(!ReadFile(stdin_handle, buf, sizeof(data->state.buffer), &readfile_read, NULL)) { keepon = FALSE; break; } nread = readfile_read; while(nread--) { outbuf[0] = *buffer++; out_count = 1; if(outbuf[0] == CURL_IAC) outbuf[out_count++] = CURL_IAC; Curl_write(conn, conn->sock[FIRSTSOCKET], outbuf, out_count, &bytes_written); } } break; case 1: if(enum_netevents_func(sockfd, event_handle, &events) != SOCKET_ERROR) { if(events.lNetworkEvents & FD_READ) { /* This reallu OUGHT to check its return code. */ (void)Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread); telrcv(conn, (unsigned char *)buf, nread); fflush(stdout); /* Negotiate if the peer has started negotiating, otherwise don't. We don't want to speak telnet with non-telnet servers, like POP or SMTP. */ if(tn->please_negotiate && !tn->already_negotiated) { negotiate(conn); tn->already_negotiated = 1; } } if(events.lNetworkEvents & FD_CLOSE) { keepon = FALSE; } } break; } } /* We called WSACreateEvent, so call WSACloseEvent */ if (close_event_func(event_handle) == FALSE) { infof(data,"WSACloseEvent failed (%d)",WSAGetLastError()); } /* "Forget" pointers into the library we're about to free */ create_event_func = NULL; close_event_func = NULL; event_select_func = NULL; enum_netevents_func = NULL; /* We called LoadLibrary, so call FreeLibrary */ if (!FreeLibrary(wsock2)) infof(data,"FreeLibrary(wsock2) failed (%d)",GetLastError()); #else FD_ZERO (&readfd); /* clear it */ FD_SET (sockfd, &readfd); FD_SET (0, &readfd); keepfd = readfd; while (keepon) { struct timeval interval; readfd = keepfd; /* set this every lap in the loop */ interval.tv_sec = 1; interval.tv_usec = 0; switch (select (sockfd + 1, &readfd, NULL, NULL, &interval)) { case -1: /* error, stop reading */ keepon = FALSE; continue; case 0: /* timeout */ break; default: /* read! */ if(FD_ISSET(0, &readfd)) { /* read from stdin */ unsigned char outbuf[2]; int out_count = 0; ssize_t bytes_written; char *buffer = buf; nread = read(0, buf, 255); while(nread--) { outbuf[0] = *buffer++; out_count = 1; if(outbuf[0] == CURL_IAC) outbuf[out_count++] = CURL_IAC; Curl_write(conn, conn->sock[FIRSTSOCKET], outbuf, out_count, &bytes_written); } } if(FD_ISSET(sockfd, &readfd)) { /* This OUGHT to check the return code... */ (void)Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread); /* if we receive 0 or less here, the server closed the connection and we bail out from this! */ if (nread <= 0) { keepon = FALSE; break; } telrcv(conn, (unsigned char *)buf, nread); /* Negotiate if the peer has started negotiating, otherwise don't. We don't want to speak telnet with non-telnet servers, like POP or SMTP. */ if(tn->please_negotiate && !tn->already_negotiated) { negotiate(conn); tn->already_negotiated = 1; } } } if(data->set.timeout) { struct timeval now; /* current time */ now = Curl_tvnow(); if(Curl_tvdiff(now, conn->created)/1000 >= data->set.timeout) { failf(data, "Time-out"); code = CURLE_OPERATION_TIMEOUTED; keepon = FALSE; } } } #endif /* mark this as "no further transfer wanted" */ Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL); return code; }
/* The following function runs in its own thread. We must therefore be very careful about what we do here. Much of condor code is not thread-safe, so we cannot use it. Unfortunately, we observed deadlocks when dprintf() was used in the following function. Therefore, dprintf is commented out. */ void SharedPortEndpoint::PipeListenerThread() { while(true) { // a bit wierd, but ConnectNamedPipe returns true on success. OR it // returns false and sets the error code to ERROR_PIPE_CONNECTED. if(!ConnectNamedPipe(pipe_end, NULL) && (GetLastError() != ERROR_PIPE_CONNECTED)) { ThreadSafeLogError("SharedPortEndpoint: Client failed to connect", GetLastError()); continue; } EnterCriticalSection(&kill_lock); if(kill_thread) { LeaveCriticalSection(&kill_lock); ThreadSafeLogError("SharedPortEndpoint: Listener thread received kill request.", 0); DisconnectNamedPipe(pipe_end); CloseHandle(pipe_end); DeleteCriticalSection(&kill_lock); return; } LeaveCriticalSection(&kill_lock); ThreadSafeLogError("SharedPortEndpoint: Pipe connected", 0); DWORD pID = GetProcessId(GetCurrentProcess()); DWORD bytes_written; BOOL written = WriteFile(pipe_end, &pID, sizeof(DWORD), &bytes_written, 0); if(!written || bytes_written != sizeof(DWORD)) { DWORD error = GetLastError(); //TODO: DO SOMETHING THREADSAFE HERE IN PLACE OF EXCEPT!!!!!!!!!!!!!!!! EXCEPT("SharedPortEndpoint: Failed to write PID, error value: %d", error); } //FlushFileBuffers(pipe_end); int expected = sizeof(WSAPROTOCOL_INFO) + sizeof(int); int buffSize = expected; char *readBuff = new char[buffSize]; char *storeBuff = new char[buffSize]; ZeroMemory(storeBuff, buffSize); DWORD bytes = 0; int total_received = 0; while(total_received < expected) { // dprintf(D_ALWAYS, "SharedPortEndpoint: Inside while loop trying to read data.\n"); if(!ReadFile(pipe_end, readBuff, buffSize, &bytes, NULL)) { // dprintf(D_ALWAYS, "SharedPortEndpoint: Failed to read data from named pipe: %d\n", GetLastError()); break; } if(bytes < buffSize) { // dprintf(D_ALWAYS, "SharedPortEndpoint: Partial read: %d\n", bytes); memcpy_s(storeBuff + (expected - buffSize), buffSize, readBuff, bytes); total_received += bytes; buffSize -= bytes; delete [] readBuff; readBuff = new char[buffSize]; continue; } //dprintf(D_ALWAYS, "SharedPortEndpoint: Read entirety of WSAPROTOCOL_INFO\n"); //total_received += bytes; int destOffset = expected - buffSize; int destLeft = expected - total_received; //dprintf(D_ALWAYS, "SharedPortEndpoint: Read: %d Offset: %d Left: %d\n", bytes, destOffset, destLeft); memcpy_s(storeBuff + destOffset, destLeft, readBuff, bytes); int cmd; memcpy_s(&cmd, sizeof(int), storeBuff, sizeof(int)); if( cmd != SHARED_PORT_PASS_SOCK ) { ThreadSafeLogError("SharedPortEndpoint: received unexpected command", cmd); break; } //WSAPROTOCOL_INFO protocol_info; WSAPROTOCOL_INFO *last_rec = (WSAPROTOCOL_INFO *)HeapAlloc(GetProcessHeap(), 0, sizeof(WSAPROTOCOL_INFO)); memcpy_s(last_rec, sizeof(WSAPROTOCOL_INFO), storeBuff+sizeof(int), sizeof(WSAPROTOCOL_INFO)); ThreadSafeLogError("SharedPortEndpoint: Copied WSAPROTOCOL_INFO", wake_select_dest ? 1 : 0); EnterCriticalSection(&received_lock); received_sockets.push(last_rec); LeaveCriticalSection(&received_lock); if(!wake_select_dest) { ThreadSafeLogError("SharedPortEndpoint: Registering Pump worker to move the socket", 0); int status = daemonCore->Register_PumpWork_TS(SharedPortEndpoint::PipeListenerHelper, this, NULL); ThreadSafeLogError("SharedPortEndpoint: back from Register_PumpWork_TS with status", status); } else { char wake[1]; wake[0] = 'A'; //wake_select_source->put_bytes(&wake, sizeof(int)); //wake_select_source->end_of_message(); int sock_fd = wake_select_source->get_file_desc(); ThreadSafeLogError("SharedPortEndpoint:CCB client, writing to socket to wake select", sock_fd); int write_success = send(sock_fd, wake, sizeof(char), 0); //TODO: DO SOMETHING THREADSAFE HERE IN PLACE OF EXCEPT!!!!!!!!!!!!!!!! if(write_success == SOCKET_ERROR) EXCEPT("SharedPortEndpoint: Failed to write to select wakeup: %d", WSAGetLastError()); } ThreadSafeLogError("SharedPortEndpoint: Finished reading from pipe", cmd); break; } delete [] readBuff; delete [] storeBuff; DisconnectNamedPipe(pipe_end); } }
//----------------------------------------------------------------------------- static void load_paths_to_exclude(LPCTSTR path) { //----------------------------------------------------------------------------- FILE * stream_p; wchar_t *get_result; size_t line_len; struct exclude_entry **link_p; struct exclude_entry * next_p; if (_wfopen_s(&stream_p, path, L"r, ccs=UTF-8")) { _wfopen_s(&error_file, error_path, L"w"); _wcserror_s(error_buffer, sizeof error_buffer/sizeof(wchar_t), errno); fwprintf( error_file, L"_wfopen(%s) failed: (%d) %s\n", path, errno, error_buffer ); fclose(error_file); ExitProcess(2); } link_p = &exclude_entry_list_p; while (1) { // create an exclude entry next_p = (struct exclude_entry *) HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct exclude_entry) ); if (next_p == NULL){ report_error(L"HeapAlloc failed to allocate memory", GetLastError()); ExitProcess(203); } // read in the path to watch from config.txt get_result = \ fgetws(full_file_name, ARRAYSIZE(full_file_name), stream_p); if (NULL == get_result) { if (0 == ferror(stream_p)) { HeapFree(GetProcessHeap(), 0, next_p); break; } _wfopen_s(&error_file, error_path, L"w"); _wcserror_s( error_buffer, sizeof error_buffer/sizeof(wchar_t) , errno ); fwprintf( error_file, L"fgetws(%s) failed: (%d) %s\n", path, errno, error_buffer ); fclose(error_file); ExitProcess(2); } // clean out the newline, if there is one line_len = wcslen(full_file_name); if (line_len && full_file_name[line_len-1] == L'\n'){ full_file_name[line_len-1] = L'\0'; line_len--; } if (full_file_name[0] == L'\0') continue; next_p->dir_path_len = line_len; next_p->dir_path = (wchar_t *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (line_len + 1) * sizeof(wchar_t)); if (next_p->dir_path == NULL){ report_error(L"HeapAlloc failed to allocate memory", GetLastError()); ExitProcess(204); } wcsncpy_s(next_p->dir_path, line_len+1, full_file_name, line_len); // add this entry to the list *link_p = next_p; // point to the new entry's next pointer link_p = &(*link_p)->next_p; } // while(1) fclose(stream_p); } // load_paths_to_exclude
static void test_SIPRetrieveSubjectGUID(void) { BOOL ret; GUID subject; HANDLE file; static const CHAR windir[] = "windir"; static const CHAR regeditExe[] = "regedit.exe"; static const GUID nullSubject = { 0x0, 0x0, 0x0, { 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0 }}; static const WCHAR deadbeef[] = { 'c',':','\\','d','e','a','d','b','e','e','f','.','d','b','f',0 }; /* Couldn't find a name for this GUID, it's the one used for 95% of the files */ static const GUID unknownGUID = { 0xC689AAB8, 0x8E78, 0x11D0, { 0x8C,0x47,0x00,0xC0,0x4F,0xC2,0x95,0xEE }}; static const GUID cabGUID = { 0xc689aaba, 0x8e78, 0x11d0, {0x8c,0x47,0x00,0xc0,0x4f,0xc2,0x95,0xee }}; static CHAR regeditPath[MAX_PATH]; static WCHAR regeditPathW[MAX_PATH]; static CHAR path[MAX_PATH]; static CHAR tempfile[MAX_PATH]; static WCHAR tempfileW[MAX_PATH]; DWORD written; /* NULL check */ SetLastError(0xdeadbeef); ret = CryptSIPRetrieveSubjectGuid(NULL, NULL, NULL); ok ( !ret, "Expected CryptSIPRetrieveSubjectGuid to fail\n"); ok (GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d.\n", GetLastError()); /* Test with a nonexistent file (hopefully) */ SetLastError(0xdeadbeef); /* Set subject to something other than zeros */ memset(&subject, 1, sizeof(GUID)); ret = CryptSIPRetrieveSubjectGuid(deadbeef, NULL, &subject); ok ( !ret, "Expected CryptSIPRetrieveSubjectGuid to fail\n"); ok (GetLastError() == ERROR_FILE_NOT_FOUND || GetLastError() == ERROR_PATH_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND or ERROR_PATH_NOT_FOUND, got %d.\n", GetLastError()); ok(IsEqualGUID(&subject, &nullSubject), "Expected a NULL GUID for c:\\deadbeef.dbf, not %s\n", wine_dbgstr_guid(&subject)); /* Now with an executable that should exist * * Use A-functions where possible as that should be available on all platforms */ ret = GetEnvironmentVariableA(windir, regeditPath, MAX_PATH); ok (ret > 0, "expected GEVA(windir) to succeed, last error %d\n", GetLastError()); strcat(regeditPath, "\\"); strcat(regeditPath, regeditExe); MultiByteToWideChar( CP_ACP, 0, regeditPath, strlen(regeditPath)+1, regeditPathW, sizeof(regeditPathW)/sizeof(regeditPathW[0]) ); SetLastError(0xdeadbeef); memset(&subject, 1, sizeof(GUID)); ret = CryptSIPRetrieveSubjectGuid(regeditPathW, NULL, &subject); ok ( ret, "Expected CryptSIPRetrieveSubjectGuid to succeed\n"); ok(IsEqualGUID(&subject, &unknownGUID), "Expected (%s), got (%s).\n", wine_dbgstr_guid(&unknownGUID), wine_dbgstr_guid(&subject)); /* The same thing but now with a handle instead of a filename */ file = CreateFileA(regeditPath, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); SetLastError(0xdeadbeef); memset(&subject, 1, sizeof(GUID)); ret = CryptSIPRetrieveSubjectGuid(NULL, file, &subject); ok ( ret, "Expected CryptSIPRetrieveSubjectGuid to succeed\n"); ok(IsEqualGUID(&subject, &unknownGUID), "Expected (%s), got (%s).\n", wine_dbgstr_guid(&unknownGUID), wine_dbgstr_guid(&subject)); CloseHandle(file); /* And both */ file = CreateFileA(regeditPath, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); SetLastError(0xdeadbeef); memset(&subject, 1, sizeof(GUID)); ret = CryptSIPRetrieveSubjectGuid(regeditPathW, file, &subject); ok ( ret, "Expected CryptSIPRetrieveSubjectGuid to succeed\n"); ok(IsEqualGUID(&subject, &unknownGUID), "Expected (%s), got (%s).\n", wine_dbgstr_guid(&unknownGUID), wine_dbgstr_guid(&subject)); CloseHandle(file); /* Now with an empty file */ GetTempPathA(sizeof(path), path); GetTempFileNameA(path, "sip", 0 , tempfile); MultiByteToWideChar( CP_ACP, 0, tempfile, strlen(tempfile)+1, tempfileW, sizeof(tempfileW)/sizeof(tempfileW[0]) ); SetLastError(0xdeadbeef); memset(&subject, 1, sizeof(GUID)); ret = CryptSIPRetrieveSubjectGuid(tempfileW, NULL, &subject); ok ( !ret, "Expected CryptSIPRetrieveSubjectGuid to fail\n"); ok ( GetLastError() == ERROR_FILE_INVALID || GetLastError() == ERROR_INVALID_PARAMETER /* Vista */ || GetLastError() == ERROR_SUCCESS /* most Win98 */ || GetLastError() == TRUST_E_SUBJECT_FORM_UNKNOWN /* some Win98 */, "Expected ERROR_FILE_INVALID, ERROR_INVALID_PARAMETER, ERROR_SUCCESS or TRUST_E_SUBJECT_FORM_UNKNOWN, got 0x%08x\n", GetLastError()); ok(IsEqualGUID(&subject, &nullSubject), "Expected a NULL GUID for empty file %s, not %s\n", tempfile, wine_dbgstr_guid(&subject)); /* Use a file with a size of 3 (at least < 4) */ file = CreateFileA(tempfile, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); WriteFile(file, "123", 3, &written, NULL); CloseHandle(file); SetLastError(0xdeadbeef); memset(&subject, 1, sizeof(GUID)); ret = CryptSIPRetrieveSubjectGuid(tempfileW, NULL, &subject); ok ( !ret, "Expected CryptSIPRetrieveSubjectGuid to fail\n"); ok ( GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_SUCCESS /* most Win98 */ || GetLastError() == TRUST_E_SUBJECT_FORM_UNKNOWN /* some Win98 */, "Expected ERROR_INVALID_PARAMETER, ERROR_SUCCESS or TRUST_E_SUBJECT_FORM_UNKNOWN, got 0x%08x\n", GetLastError()); ok(IsEqualGUID(&subject, &nullSubject), "Expected a NULL GUID for empty file %s, not %s\n", tempfile, wine_dbgstr_guid(&subject)); /* And now >= 4 */ file = CreateFileA(tempfile, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); WriteFile(file, "1234", 4, &written, NULL); CloseHandle(file); SetLastError(0xdeadbeef); memset(&subject, 1, sizeof(GUID)); ret = CryptSIPRetrieveSubjectGuid(tempfileW, NULL, &subject); ok ( !ret, "Expected CryptSIPRetrieveSubjectGuid to fail\n"); ok ( GetLastError() == TRUST_E_SUBJECT_FORM_UNKNOWN || GetLastError() == ERROR_SUCCESS /* Win98 */, "Expected TRUST_E_SUBJECT_FORM_UNKNOWN or ERROR_SUCCESS, got 0x%08x\n", GetLastError()); ok(IsEqualGUID(&subject, &nullSubject), "Expected a NULL GUID for empty file %s, not %s\n", tempfile, wine_dbgstr_guid(&subject)); /* Clean up */ DeleteFileA(tempfile); /* Create a file with just the .cab header 'MSCF' */ SetLastError(0xdeadbeef); file = CreateFileA(tempfile, GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, NULL); ok(file != INVALID_HANDLE_VALUE, "failed with %u\n", GetLastError()); WriteFile(file, cabFileData, 4, &written, NULL); CloseHandle(file); SetLastError(0xdeadbeef); memset(&subject, 1, sizeof(GUID)); ret = CryptSIPRetrieveSubjectGuid(tempfileW, NULL, &subject); ok( ret, "CryptSIPRetrieveSubjectGuid failed: %d (0x%08x)\n", GetLastError(), GetLastError() ); ok(IsEqualGUID(&subject, &cabGUID), "Expected GUID %s for cabinet file, not %s\n", wine_dbgstr_guid(&cabGUID), wine_dbgstr_guid(&subject)); /* Clean up */ DeleteFileA(tempfile); /* Create a .cab file */ SetLastError(0xdeadbeef); file = CreateFileA(tempfile, GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, NULL); ok(file != INVALID_HANDLE_VALUE, "failed with %u\n", GetLastError()); WriteFile(file, cabFileData, sizeof(cabFileData), &written, NULL); CloseHandle(file); SetLastError(0xdeadbeef); memset(&subject, 1, sizeof(GUID)); ret = CryptSIPRetrieveSubjectGuid(tempfileW, NULL, &subject); ok( ret, "CryptSIPRetrieveSubjectGuid failed: %d (0x%08x)\n", GetLastError(), GetLastError() ); ok(IsEqualGUID(&subject, &cabGUID), "Expected GUID %s for cabinet file, not %s\n", wine_dbgstr_guid(&cabGUID), wine_dbgstr_guid(&subject)); /* Clean up */ DeleteFileA(tempfile); }
//----------------------------------------------------------------------------- int APIENTRY _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow ) { //----------------------------------------------------------------------------- int num_args; int parent_pid; HANDLE hParent; HANDLE completion_port_h; LPWSTR * args_p; BOOL get_successful; DWORD bytes_returned; struct watch_entry * watch_entry_p; ULONG_PTR completion_key; int loop_count; /* Python's subprocess doesn't use the widechar API (CreateProcessW) in Python 2.x. In order to support non-ascii characters, the command line is encoded in utf-8 and decoded manually here. */ int required_len; WCHAR *command_line; LPSTR utf8_command_line = GetCommandLineA(); required_len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, utf8_command_line, -1, NULL, 0); if (required_len == 0) return GetLastError(); command_line = (WCHAR *)malloc(required_len * sizeof(WCHAR)); if (command_line == NULL) return ERROR_OUTOFMEMORY; required_len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, utf8_command_line, -1, command_line, required_len); if (required_len == 0) return GetLastError(); args_p = CommandLineToArgvW(command_line, &num_args); if (args_p == NULL) return GetLastError(); if (num_args != 5) { return 1; } notification_path = args_p[4]; wsprintf(error_path, L"%s\\error.txt", notification_path); wsprintf(temp_file_path, L"%s\\temp", notification_path); memset(error_buffer, '\0', sizeof(error_buffer)); // create the basic completion port completion_port_h = CreateIoCompletionPort( INVALID_HANDLE_VALUE, // FileHandle, NULL, // ExistingCompletionPort, 0, // CompletionKey, 0 // NumberOfConcurrentThreads ); if (NULL == completion_port_h) { report_error(L"CreateIoCompletionPort", GetLastError()); ExitProcess(100); } parent_pid = _wtoi(args_p[1]); // Use 0 for debugging if (parent_pid == 0) hParent = NULL; else{ hParent = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, parent_pid); if (hParent == NULL){ report_error(L"OpenProcess", GetLastError()); ExitProcess(105); } } load_paths_to_watch(args_p[2], completion_port_h); if (NULL == watch_entry_list_p) { return 0; } load_paths_to_exclude(args_p[3]); loop_count = 0; while (TRUE) { loop_count += 1; watch_entry_p = NULL; get_successful = GetQueuedCompletionStatus( completion_port_h, &bytes_returned, &completion_key, (LPOVERLAPPED *) &watch_entry_p, TIMEOUT_MILLESECONDS ); if (!get_successful) { if (NULL == watch_entry_p) { // timeout: make sure our parent is still running if (parent_is_gone(hParent)) { break; } else { continue; } } report_error(L"GetQueuedCompletionStatus", GetLastError()); ExitProcess(115); } process_dir_watcher_results(watch_entry_p, bytes_returned); // start a new watch start_watch(watch_entry_p); if (loop_count % PARENT_CHECK_COUNT == 0) { if (parent_is_gone(hParent)) { break; } } } // while (TRUE) { // We get here if we think the parent is gone return 0; } // _tWinMain
static void test_SIPLoad(void) { BOOL ret; GUID subject; static GUID dummySubject = { 0xdeadbeef, 0xdead, 0xbeef, { 0xde,0xad,0xbe,0xef,0xde,0xad,0xbe,0xef }}; static GUID unknown = { 0xC689AABA, 0x8E78, 0x11D0, { 0x8C,0x47,0x00,0xC0,0x4F,0xC2,0x95,0xEE }}; /* WINTRUST.DLL */ static GUID unknown2 = { 0xDE351A43, 0x8E59, 0x11D0, { 0x8C,0x47,0x00,0xC0,0x4F,0xC2,0x95,0xEE }}; /* WINTRUST.DLL */ /* The next SIP is available on Windows and on Wine */ static GUID unknown3 = { 0x000C10F1, 0x0000, 0x0000, { 0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 }}; /* MSISIP.DLL */ SIP_DISPATCH_INFO sdi; HMODULE hCrypt; /* All NULL */ SetLastError(0xdeadbeef); ret = CryptSIPLoad(NULL, 0, NULL); ok ( !ret, "Expected CryptSIPLoad to fail\n"); ok ( GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got 0x%08x\n", GetLastError()); /* Only pSipDispatch NULL */ SetLastError(0xdeadbeef); ret = CryptSIPLoad(&subject, 0, NULL); ok ( !ret, "Expected CryptSIPLoad to fail\n"); ok ( GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got 0x%08x\n", GetLastError()); /* No NULLs, but nonexistent pgSubject */ SetLastError(0xdeadbeef); memset(&sdi, 0, sizeof(SIP_DISPATCH_INFO)); sdi.cbSize = sizeof(SIP_DISPATCH_INFO); sdi.pfGet = (pCryptSIPGetSignedDataMsg)0xdeadbeef; ret = CryptSIPLoad(&dummySubject, 0, &sdi); ok ( !ret, "Expected CryptSIPLoad to fail\n"); ok ( GetLastError() == TRUST_E_SUBJECT_FORM_UNKNOWN, "Expected TRUST_E_SUBJECT_FORM_UNKNOWN, got 0x%08x\n", GetLastError()); ok( sdi.pfGet == (pCryptSIPGetSignedDataMsg)0xdeadbeef, "Expected no change to the function pointer\n"); hCrypt = GetModuleHandleA("crypt32.dll"); funcCryptSIPGetSignedDataMsg = (void*)GetProcAddress(hCrypt, "CryptSIPGetSignedDataMsg"); funcCryptSIPPutSignedDataMsg = (void*)GetProcAddress(hCrypt, "CryptSIPPutSignedDataMsg"); funcCryptSIPCreateIndirectData = (void*)GetProcAddress(hCrypt, "CryptSIPCreateIndirectData"); funcCryptSIPVerifyIndirectData = (void*)GetProcAddress(hCrypt, "CryptSIPVerifyIndirectData"); funcCryptSIPRemoveSignedDataMsg = (void*)GetProcAddress(hCrypt, "CryptSIPRemoveSignedDataMsg"); /* All OK */ SetLastError(0xdeadbeef); memset(&sdi, 0, sizeof(SIP_DISPATCH_INFO)); sdi.cbSize = sizeof(SIP_DISPATCH_INFO); sdi.pfGet = (pCryptSIPGetSignedDataMsg)0xdeadbeef; ret = CryptSIPLoad(&unknown, 0, &sdi); ok ( ret, "Expected CryptSIPLoad to succeed\n"); /* On native the last error will always be ERROR_PROC_NOT_FOUND as native searches for the function DllCanUnloadNow * in WINTRUST.DLL (in this case). This function is not available in WINTRUST.DLL. * For now there's no need to implement this is Wine as I doubt any program will rely on * this last error when the call succeeded. */ ok( sdi.pfGet != (pCryptSIPGetSignedDataMsg)0xdeadbeef, "Expected a function pointer to be loaded.\n"); /* The function addresses returned by CryptSIPLoad are actually the addresses of * crypt32's own functions. A function calling these addresses will end up first * calling crypt32 functions which in its turn call the equivalent in the SIP * as dictated by the given GUID. */ if (funcCryptSIPGetSignedDataMsg && funcCryptSIPPutSignedDataMsg && funcCryptSIPCreateIndirectData && funcCryptSIPVerifyIndirectData && funcCryptSIPRemoveSignedDataMsg) ok (sdi.pfGet == funcCryptSIPGetSignedDataMsg && sdi.pfPut == funcCryptSIPPutSignedDataMsg && sdi.pfCreate == funcCryptSIPCreateIndirectData && sdi.pfVerify == funcCryptSIPVerifyIndirectData && sdi.pfRemove == funcCryptSIPRemoveSignedDataMsg, "Expected function addresses to be from crypt32\n"); else trace("Couldn't load function pointers\n"); /* All OK, but different GUID (same SIP though) */ SetLastError(0xdeadbeef); memset(&sdi, 0, sizeof(SIP_DISPATCH_INFO)); sdi.cbSize = sizeof(SIP_DISPATCH_INFO); sdi.pfGet = (pCryptSIPGetSignedDataMsg)0xdeadbeef; ret = CryptSIPLoad(&unknown2, 0, &sdi); ok ( ret, "Expected CryptSIPLoad to succeed\n"); /* This call on its own would have resulted in an ERROR_PROC_NOT_FOUND, but the previous * call to CryptSIPLoad already loaded wintrust.dll. As this information is cached, * CryptSIPLoad will not try to search for the already mentioned DllCanUnloadNow. */ ok( sdi.pfGet != (pCryptSIPGetSignedDataMsg)0xdeadbeef, "Expected a function pointer to be loaded.\n"); /* All OK, but other SIP */ SetLastError(0xdeadbeef); memset(&sdi, 0, sizeof(SIP_DISPATCH_INFO)); sdi.cbSize = sizeof(SIP_DISPATCH_INFO); sdi.pfGet = (pCryptSIPGetSignedDataMsg)0xdeadbeef; ret = CryptSIPLoad(&unknown3, 0, &sdi); if (ret) { /* The SIP is known so we can safely assume that the next tests can be done */ /* As msisip.dll is not checked yet by any of the previous calls, the * function DllCanUnloadNow will be checked again in msisip.dll (it's not present) */ ok( sdi.pfGet != (pCryptSIPGetSignedDataMsg)0xdeadbeef, "Expected a function pointer to be loaded.\n"); /* This is another SIP but this test proves the function addresses are the same as * in the previous test. */ if (funcCryptSIPGetSignedDataMsg && funcCryptSIPPutSignedDataMsg && funcCryptSIPCreateIndirectData && funcCryptSIPVerifyIndirectData && funcCryptSIPRemoveSignedDataMsg) ok (sdi.pfGet == funcCryptSIPGetSignedDataMsg && sdi.pfPut == funcCryptSIPPutSignedDataMsg && sdi.pfCreate == funcCryptSIPCreateIndirectData && sdi.pfVerify == funcCryptSIPVerifyIndirectData && sdi.pfRemove == funcCryptSIPRemoveSignedDataMsg, "Expected function addresses to be from crypt32\n"); else trace("Couldn't load function pointers\n"); } /* Reserved parameter not 0 */ SetLastError(0xdeadbeef); memset(&sdi, 0, sizeof(SIP_DISPATCH_INFO)); sdi.cbSize = sizeof(SIP_DISPATCH_INFO); sdi.pfGet = (pCryptSIPGetSignedDataMsg)0xdeadbeef; ret = CryptSIPLoad(&unknown, 1, &sdi); ok ( !ret, "Expected CryptSIPLoad to fail\n"); ok ( GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got 0x%08x\n", GetLastError()); ok( sdi.pfGet == (pCryptSIPGetSignedDataMsg)0xdeadbeef, "Expected no change to the function pointer\n"); }
void MI_CALL MSFT_DSCLocalConfigManager_Invoke_GetConfiguration( _In_opt_ MSFT_DSCLocalConfigManager_Self* self, _In_ MI_Context* context, _In_opt_z_ const MI_Char* nameSpace, _In_opt_z_ const MI_Char* className, _In_opt_z_ const MI_Char* methodName, _In_ const MSFT_DSCLocalConfigManager* instanceName, _In_opt_ const MSFT_DSCLocalConfigManager_GetConfiguration* in) { MI_Result miResult; MI_Instance *cimErrorDetails = NULL; MI_InstanceA outInstances = {0}; MI_Value val; MI_Uint32 bufferIndex = 0; MSFT_DSCLocalConfigManager_GetConfiguration outputObject; HANDLE m_clientThreadToken; MI_UNREFERENCED_PARAMETER(self); MI_UNREFERENCED_PARAMETER(nameSpace); MI_UNREFERENCED_PARAMETER(className); MI_UNREFERENCED_PARAMETER(methodName); MI_UNREFERENCED_PARAMETER(instanceName); MI_UNREFERENCED_PARAMETER(in); if(!in->configurationData.exists) { MI_Context_PostResult(context, MI_RESULT_INVALID_PARAMETER); return; } if(!OpenThreadToken(GetCurrentThread(), TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_DUPLICATE, TRUE, &m_clientThreadToken)) { GetCimWin32Error(GetLastError(), &cimErrorDetails, ID_LCMHELPER_THREADIMPERSONATION_FAILED); MI_PostCimError(context, cimErrorDetails); MI_Instance_Delete(cimErrorDetails); return; } if (!SetThreadToken(NULL, NULL)) { GetCimWin32Error(GetLastError(), &cimErrorDetails, ID_LCMHELPER_REVERTSELF_FAILED); MI_PostCimError(context, cimErrorDetails); MI_Instance_Delete(cimErrorDetails); CloseHandle(m_clientThreadToken); return; } miResult = MSFT_DSCLocalConfigManager_GetConfiguration_Construct(&outputObject, context); if(miResult != MI_RESULT_OK) { GetCimMIError(miResult, &cimErrorDetails, ID_LCMHELPER_CONSTRUCTGET_FAILED); MI_PostCimError(context, cimErrorDetails); MI_Instance_Delete(cimErrorDetails); return; } GetRealBufferIndex( &(in->configurationData.value), &bufferIndex); miResult = CallGetConfiguration(in->configurationData.value.data + bufferIndex, in->configurationData.value.size - bufferIndex, &outInstances, context, &cimErrorDetails); if(miResult != MI_RESULT_OK) { MI_PostCimError(context, cimErrorDetails); MI_Instance_Delete(cimErrorDetails); MSFT_DSCLocalConfigManager_GetConfiguration_Destruct(&outputObject); SetThreadToken(NULL, m_clientThreadToken); CloseHandle(m_clientThreadToken); return; } val.instancea.data = outInstances.data; val.instancea.size = outInstances.size; miResult = MI_Context_WriteStreamParameter(context, L"configurations", &val, MI_INSTANCEA, 0); CleanUpInstanceCache(&outInstances); if(miResult != MI_RESULT_OK) { GetCimMIError(miResult, &cimErrorDetails, ID_LCMHELPER_WRITEGET_FAILED); MI_PostCimError(context, cimErrorDetails); MI_Instance_Delete(cimErrorDetails); MSFT_DSCLocalConfigManager_GetConfiguration_Destruct(&outputObject); SetThreadToken(NULL, m_clientThreadToken); CloseHandle(m_clientThreadToken); return; } miResult = MSFT_DSCLocalConfigManager_GetConfiguration_Set_MIReturn(&outputObject, 0); if(miResult != MI_RESULT_OK) { GetCimMIError(miResult, &cimErrorDetails, ID_LCMHELPER_SETGET_FAILED); MI_PostCimError(context, cimErrorDetails); MI_Instance_Delete(cimErrorDetails); MSFT_DSCLocalConfigManager_GetConfiguration_Destruct(&outputObject); SetThreadToken(NULL, m_clientThreadToken); CloseHandle(m_clientThreadToken); return; } miResult = MSFT_DSCLocalConfigManager_GetConfiguration_Post(&outputObject, context); MSFT_DSCLocalConfigManager_GetConfiguration_Destruct(&outputObject); if (!SetThreadToken(NULL, m_clientThreadToken)) { GetCimWin32Error(GetLastError(), &cimErrorDetails, ID_LCMHELPER_RESUMEIMPERSONATION_FAILED); MI_PostCimError(context, cimErrorDetails); MI_Instance_Delete(cimErrorDetails); CloseHandle(m_clientThreadToken); return; } CloseHandle(m_clientThreadToken); if(miResult != MI_RESULT_OK) { GetCimMIError(miResult, &cimErrorDetails, ID_LCMHELPER_POSTGET_FAILED); MI_PostCimError(context, cimErrorDetails); MI_Instance_Delete(cimErrorDetails); return; } MI_Context_PostResult(context, MI_RESULT_OK); }
int __cdecl main(int argc, char *argv[]) { char mbStr[128]; WCHAR wideStr[128]; int ret; int i; int k; BOOL bRet=TRUE; /* These codepages are currently supported by the PAL */ int codePages[] ={ CP_ACP, 932, 949, 950, 1252, 1258, CP_UTF8 }; if (PAL_Initialize(argc, argv)) { return FAIL; } /* Go through all of the code pages */ for(i=0; i<(sizeof(codePages)/sizeof(int)); i++) { for (k=0; k<128; k++) { wideStr[k] = 'a'; mbStr[k] = 0; } wideStr[127] = 0; /* try with insufficient buffer space */ ret = WideCharToMultiByte(codePages[i], 0, wideStr, -1, mbStr, 10, NULL, NULL); if (ret != 0) { Trace("WideCharToMultiByte did not return an error!\n" "Expected return of 0, got %d for code page %d.\n", ret, codePages[i]); bRet = FALSE; } ret = GetLastError(); if (ret != ERROR_INSUFFICIENT_BUFFER) { Fail("WideCharToMultiByte set the last error to %u instead of " "ERROR_INSUFFICIENT_BUFFER for code page %d.\n", GetLastError(),codePages[i]); bRet = FALSE; } } /* Return failure if any of the code pages returned the wrong results */ if(!bRet) { return FAIL; } /* try with a wacky code page */ ret = WideCharToMultiByte(-1, 0, wideStr, -1, mbStr, 128, NULL, NULL); if (ret != 0) { Fail("WideCharToMultiByte did not return an error!\n" "Expected return of 0, got %d for invalid code page.\n", ret); } ret = GetLastError(); if (ret != ERROR_INVALID_PARAMETER) { Fail("WideCharToMultiByte set the last error to %u instead of " "ERROR_INVALID_PARAMETER for invalid code page -1.\n", GetLastError()); } PAL_Terminate(); return PASS; }