static __forceinline void doLockFile(HANDLE &fileHandle, const QString &filePath, QFile *const outFile) { bool success = false; fileHandle = INVALID_HANDLE_VALUE; //Try to open the file! for(int i = 0; i < 64; i++) { const HANDLE hTemp = CreateFileW(MUTILS_WCHR(QDir::toNativeSeparators(filePath)), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL); if(VALID_HANDLE(hTemp)) { PROTECT_HANDLE(fileHandle = hTemp, true); break; /*file opened successfully*/ } if(i == 0) { qWarning("Failed to open file on first attemp, retrying..."); } Sleep(1); } //Now try to actually lock the file! if (VALID_HANDLE(fileHandle)) { for (int i = 0; i < 64; i++) { LARGE_INTEGER fileSize; if (GetFileSizeEx(fileHandle, &fileSize)) { OVERLAPPED overlapped = { 0U, 0U, 0U, 0U, 0U }; if (LockFileEx(fileHandle, LOCKFILE_FAIL_IMMEDIATELY, 0, fileSize.LowPart, fileSize.HighPart, &overlapped)) { success = true; break; /*file locked successfully*/ } Sleep(1); } if (i == 0) { qWarning("Failed to lock file on first attemp, retrying..."); } } } //Locked successfully? if(!success) { CLOSE_HANDLE(fileHandle); if(outFile) { QFile::remove(QFileInfo(*outFile).canonicalFilePath()); } MUTILS_THROW_FMT("File '%s' could not be locked!", MUTILS_UTF8(QFileInfo(filePath).fileName())); } }
/** * * DESCRIPTION: This function causes the next available thread in the pend queue * to be unblocked. If no thread is pending on this semaphore, the * semaphore becomes 'full'. */ PUBLIC IX_STATUS ixOsalSemaphorePost(IxOsalSemaphore *sid) { VALID_HANDLE(sid); struct semaphore *sem = *sid; L4_ThreadId_t tid = { 0 }; /*Get the lock, up the value, take the head, and get out*/ ixOsalFastMutexLock(&sem->fInterlockP); if (sem->fQueue) { assert((int) sem->fCount < 0); // Hand the count over to the next thread struct tid_list *head = sem->fQueue; tid = head->fTid; sem->fQueue = head->fNext; // Drop the node, it will be freed later } sem->fCount++; ixOsalFastMutexUnlock(&sem->fInterlockP); // Ping the waiting thread if any if (tid.raw) { L4_LoadMR(0, 0); // Empty message L4_Send_Nonblocking(tid); } return IX_SUCCESS; }
static int MyShellDispatch_ShellDispatchProc(const shell_dispatch_handler_t handler, void *const data) { int iSuccess = SHELL_DISPATCH_FAILED; IShellWindows *psw = NULL; HRESULT hr = CoCreateInstance(CLSID_ShellWindows, NULL, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&psw)); if(SUCCEEDED(hr)) { HWND desktopHwnd = 0; IDispatch* pdisp = NULL; variant_t vEmpty; if(S_OK == psw->FindWindowSW(vEmpty, vEmpty, SWC_DESKTOP, (long*)&desktopHwnd, SWFO_NEEDDISPATCH, &pdisp)) { if(VALID_HANDLE(desktopHwnd)) { IShellBrowser *psb; hr = IUnknown_QueryService(pdisp, SID_STopLevelBrowser, IID_PPV_ARGS(&psb)); if(SUCCEEDED(hr)) { IShellView *psv = NULL; hr = psb->QueryActiveShellView(&psv); if(SUCCEEDED(hr)) { IDispatch *pdispBackground = NULL; HRESULT hr = psv->GetItemObject(SVGIO_BACKGROUND, IID_PPV_ARGS(&pdispBackground)); if(SUCCEEDED(hr)) { MyShellDispatch_AllowSetForegroundWindow(desktopHwnd); IShellFolderViewDual *psfvd = NULL; HRESULT hr = pdispBackground->QueryInterface(IID_PPV_ARGS(&psfvd)); if(SUCCEEDED(hr)) { IDispatch *pdisp = NULL; hr = psfvd->get_Application(&pdisp); if(SUCCEEDED(hr)) { IShellDispatch2 *pShellDispatch; hr = pdisp->QueryInterface(IID_PPV_ARGS(&pShellDispatch)); if(SUCCEEDED(hr)) { iSuccess = handler(pShellDispatch, data); } RELEASE_OBJ(pdisp); } RELEASE_OBJ(psfvd); } RELEASE_OBJ(pdispBackground); } RELEASE_OBJ(psv); } RELEASE_OBJ(psb); } } RELEASE_OBJ(pdisp); } RELEASE_OBJ(psw); } return iSuccess; }
int MyShellDispatch(const shell_dispatch_handler_t handler, void *const data, const bool &threaded) { int iSuccess = SHELL_DISPATCH_FAILED; if(threaded) { threadParam_t threadParams = { (-1), handler, data }; HANDLE hThread = (HANDLE) _beginthreadex(NULL, 0, ShellTest_ThreadHelperProc, &threadParams, 0, NULL); if(VALID_HANDLE(hThread)) { DWORD status = WaitForSingleObject(hThread, 30000); if(status == WAIT_OBJECT_0) { iSuccess = threadParams.returnValue; } else if(status == WAIT_TIMEOUT) { iSuccess = SHELL_DISPATCH_TIMEOUT; TerminateThread(hThread, EXIT_FAILURE); } CloseHandle(hThread); } } else { iSuccess = MyShellDispatch_ShellDispatchProc(handler, data); } return iSuccess; }
static void CLOSE_HANDLE(HANDLE &h) { if(VALID_HANDLE(h)) { PROTECT_HANDLE(h, false); CloseHandle(h); } h = NULL; }
PUBLIC IX_STATUS ixOsalSemaphoreDestroy (IxOsalSemaphore *sid) { VALID_HANDLE(sid); free(*sid); *sid = 0; return IX_SUCCESS; }
PUBLIC IX_STATUS ixOsalSemaphoreGetValue (IxOsalSemaphore * sid, UINT32 * value) { VALID_HANDLE(sid); assert(value); struct semaphore *sem = *sid; *value = sem->fCount; return IX_SUCCESS; }
PUBLIC IX_STATUS ixOsalFastMutexUnlock(IxOsalFastMutex *mutex) { VALID_HANDLE(mutex); struct mutex *mtx = (struct mutex *) *mutex; mtx->fHolder = 0; if (mtx->fNeeded) { mtx->fNeeded = 0; L4_ThreadSwitch(L4_nilthread); } return IX_SUCCESS; }
bool ComputeHash_FromFile(const int hashType, const TCHAR *const fileName, TCHAR *const hashOut, const size_t hashOutSize) { const size_t hashSize = GetHashSize(hashType); if((hashSize == SIZE_MAX) || (hashSize >= (hashOutSize / 2))) { if(hashSize != SIZE_MAX) ERROR_MSG(T("Output buffer is too small to hold the hash value!")); return false; } HANDLE h = CreateFile(fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if(!VALID_HANDLE(h)) { ERROR_MSG(T("Failed to open input file for reading!")); return false; } hash_ctx ctx; if(!HashFunction_Init(hashType, &ctx)) { CLOSE_HANDLE(h); return false; } static const DWORD BUFF_SIZE = 4096; BYTE buffer[BUFF_SIZE]; for(;;) { DWORD nBytesRead = 0; if(!ReadFile(h, buffer, BUFF_SIZE, &nBytesRead, NULL)) { ERROR_MSG(T("Failed to read data from input file!")); CLOSE_HANDLE(h); return false; } if(nBytesRead < 1) { CLOSE_HANDLE(h); break; } HashFunction_Update(&ctx, buffer, nBytesRead); } BYTE hashValue[128]; HashFunction_Final(&ctx, hashValue); ConvertHashToHex(hashSize, hashValue, hashOut); return true; }
PUBLIC IX_STATUS ixOsalSemaphoreWait (IxOsalOsSemaphore *sid, INT32 timeout) { VALID_HANDLE(sid); struct semaphore *sem = *sid; UINT32 start, duration; if (timeout == IX_OSAL_WAIT_FOREVER) return ixOsalSemaphoreWaitInternal(sem, /* wait */ true); IX_STATUS ixStatus = ixOsalSemaphoreWaitInternal(sem, /* wait */ false); if (!timeout || ixStatus == IX_SUCCESS) return ixStatus; start = IX_OSAL_OEM_TIMESTAMP_GET(); duration = US_TO_TICKS(timeout * 1000); do { ixOsalYield(); ixStatus = ixOsalSemaphoreWaitInternal(sem, /* wait */ false); } while (ixStatus != IX_SUCCESS && IX_OSAL_OEM_TIMESTAMP_GET() - start < duration); return ixStatus; }