void worker_thread_impl::wakeup( ) { QueueUserAPC( []( ULONG_PTR ) {}, get_internals( ).thr.native_handle( ), 0 ); }
void inline CShellBrowser::InsertAwaitingItems(BOOL bInsertIntoGroup) { LVITEM lv; ULARGE_INTEGER ulFileSize; unsigned int nPrevItems; int nAdded = 0; int iItemIndex; nPrevItems = ListView_GetItemCount(m_hListView); m_nAwaitingAdd = (int)m_AwaitingAddList.size(); if((nPrevItems + m_nAwaitingAdd) == 0) { if(m_bApplyFilter) SendMessage(m_hOwner,WM_USER_FILTERINGAPPLIED,m_ID,TRUE); else SendMessage(m_hOwner,WM_USER_FOLDEREMPTY,m_ID,TRUE); m_nTotalItems = 0; return; } else if(!m_bApplyFilter) { SendMessage(m_hOwner,WM_USER_FOLDEREMPTY,m_ID,FALSE); } /* Make the listview allocate space (for internal data structures) for all the items at once, rather than individually. Acts as a speed optimization. */ ListView_SetItemCount(m_hListView,m_nAwaitingAdd + nPrevItems); lv.mask = LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM; if(bInsertIntoGroup) lv.mask |= LVIF_GROUPID; /* Constant for each item. */ lv.iSubItem = 0; if(m_bAutoArrange) NListView::ListView_SetAutoArrange(m_hListView,FALSE); for(auto itr = m_AwaitingAddList.begin();itr != m_AwaitingAddList.end();itr++) { if(!IsFileFiltered(itr->iItemInternal)) { lv.iItem = itr->iItem; lv.pszText = ProcessItemFileName(itr->iItemInternal); lv.iImage = I_IMAGECALLBACK; lv.lParam = itr->iItemInternal; if(bInsertIntoGroup) { lv.iGroupId = DetermineItemGroup(itr->iItemInternal); } /* Insert the item into the list view control. */ iItemIndex = ListView_InsertItem(m_hListView,&lv); if(itr->bPosition && m_ViewMode != VM_DETAILS) { POINT ptItem; if(itr->iAfter != -1) { ListView_GetItemPosition(m_hListView,itr->iAfter,&ptItem); } else { ptItem.x = 0; ptItem.y = 0; } /* The item will end up in the position AFTER iAfter. */ ListView_SetItemPosition32(m_hListView,iItemIndex,ptItem.x,ptItem.y); } if(m_ViewMode == VM_TILES) { SetTileViewItemInfo(iItemIndex,itr->iItemInternal); } if(m_bNewItemCreated) { LPITEMIDLIST pidlComplete = NULL; pidlComplete = ILCombine(m_pidlDirectory,m_pExtraItemInfo[(int)itr->iItemInternal].pridl); if(CompareIdls(pidlComplete,m_pidlNewItem)) m_bNewItemCreated = FALSE; m_iIndexNewItem = iItemIndex; CoTaskMemFree(pidlComplete); } /* If the file is marked as hidden, ghost it out. */ if(m_pwfdFiles[itr->iItemInternal].dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) { ListView_SetItemState(m_hListView,iItemIndex,LVIS_CUT,LVIS_CUT); } /* Add the current file's size to the running size of the current directory. */ /* A folder may or may not have 0 in its high file size member. It should either be zeroed, or never counted. */ ulFileSize.LowPart = m_pwfdFiles[itr->iItemInternal].nFileSizeLow; ulFileSize.HighPart = m_pwfdFiles[itr->iItemInternal].nFileSizeHigh; m_ulTotalDirSize.QuadPart += ulFileSize.QuadPart; nAdded++; } else { m_FilteredItemsList.push_back(itr->iItemInternal); } } if(m_bAutoArrange) NListView::ListView_SetAutoArrange(m_hListView,TRUE); m_nTotalItems = nPrevItems + nAdded; if(m_ViewMode == VM_DETAILS) { TCHAR szDrive[MAX_PATH]; BOOL bNetworkRemovable = FALSE; QueueUserAPC(SetAllColumnDataAPC,m_hThread,(ULONG_PTR)this); StringCchCopy(szDrive,SIZEOF_ARRAY(szDrive),m_CurDir); PathStripToRoot(szDrive); if(GetDriveType(szDrive) == DRIVE_REMOVABLE || GetDriveType(szDrive) == DRIVE_REMOTE) { bNetworkRemovable = TRUE; } /* If the user has selected to disable folder sizes on removable drives or networks, and we are currently on such a drive, do not calculate folder sizes. */ if(m_bShowFolderSizes && !(m_bDisableFolderSizesNetworkRemovable && bNetworkRemovable)) QueueUserAPC(SetAllFolderSizeColumnDataAPC,m_hFolderSizeThread,(ULONG_PTR)this); } PositionDroppedItems(); m_AwaitingAddList.clear(); m_nAwaitingAdd = 0; }
int __cdecl main (int argc, char **argv) { HANDLE hThread = NULL; int ret; int i,j; BOOL bResult = FAIL; PAPCFUNC APCFuncs[] = { APCFuncA, APCFuncB, APCFuncC, APCFuncD, }; /* initialize the PAL */ if (0 != (PAL_Initialize(argc, argv))) { return FAIL; } ResultPtr = ResultBuffer; /* create a pair of synchronization events to coordinate our threads */ hSyncEvent1 = CreateEvent( NULL, FALSE, FALSE, NULL ); if( hSyncEvent1 == NULL ) { Trace( "ERROR:%lu:CreateEvent() call failed\n", GetLastError() ); goto cleanup; } hSyncEvent2 = CreateEvent( NULL, FALSE, FALSE, NULL ); if( hSyncEvent2 == NULL ) { Trace( "ERROR:%lu:CreateEvent() call failed\n", GetLastError() ); goto cleanup; } /* create a child thread which will call SleepEx */ hThread = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)SleeperProc, 0, 0, &ChildThread); if( hThread == NULL ) { Trace( "ERROR:%lu:CreateThread() call failed\n", GetLastError()); goto cleanup; } /* wait on our synchronization event to ensure the thread is running */ ret = WaitForSingleObject( hSyncEvent1, 20000 ); if( ret != WAIT_OBJECT_0 ) { Trace( "ERROR:WaitForSingleObject() returned %lu, " "expected WAIT_OBJECT_0\n", ret ); goto cleanup; } /* queue our user APC functions on the thread */ for (i=0; i<4; i++) { for (j=0; j<sizeof(APCFuncs)/sizeof(APCFuncs[0]); j++) { ret = QueueUserAPC(APCFuncs[j], hThread, '0' + i); if (ret == 0) { Trace( "ERROR:%lu:QueueUserAPC() call failed\n", GetLastError()); goto cleanup; } } } /* signal the child thread to continue */ if( ! SetEvent( hSyncEvent2 ) ) { Trace( "ERROR:%lu:SetEvent() call failed\n", GetLastError() ); goto cleanup; } /* wait on our synchronization event to ensure the other thread is done */ ret = WaitForSingleObject( hSyncEvent1, 20000 ); if( ret != WAIT_OBJECT_0 ) { Trace( "ERROR:WaitForSingleObject() returned %lu, " "expected WAIT_OBJECT_0\n", ret ); goto cleanup; } /* check that the thread executed successfully */ if( bThreadResult == FAIL ) { goto cleanup; } /* check the result buffer */ if (strcmp(ExpectedResults, ResultBuffer) != 0) { Trace( "FAIL:Expected the APC function calls to produce a result of " " \"%s\", got \"%s\"\n", ExpectedResults, ResultBuffer ); goto cleanup; } /* success if we get here */ bResult = PASS; cleanup: /* wait for the other thread to finish */ if( hThread != NULL ) { ret = WaitForSingleObject( hThread, INFINITE ); if (ret == WAIT_FAILED) { Trace( "ERROR:%lu:WaitForSingleObject() returned %lu, " "expected WAIT_OBJECT_0\n", ret ); bResult = FAIL; } } /* close our synchronization handles */ if( hSyncEvent1 != NULL ) { if( ! CloseHandle( hSyncEvent1 ) ) { Trace( "ERROR:%lu:CloseHandle() call failed\n", GetLastError() ); bResult = FAIL; } } if( hSyncEvent2 != NULL ) { if( ! CloseHandle( hSyncEvent2 ) ) { Trace( "ERROR:%lu:CloseHandle() call failed\n", GetLastError() ); bResult = FAIL; } } if( bResult == FAIL ) { Fail( "test failed\n" ); } /* terminate the PAL */ PAL_Terminate(); /* return success */ return PASS; }
int __cdecl main( int argc, char **argv ) { /* local variables */ HANDLE hThread = NULL; DWORD IDThread; DWORD ret; /* PAL initialization */ if( (PAL_Initialize(argc, argv)) != 0 ) { return( FAIL ); } /* run another dummy thread to cause notification of the library */ hThread = CreateThread( NULL, /* no security attributes */ 0, /* use default stack size */ (LPTHREAD_START_ROUTINE) ThreadFunc, /* thread function */ (LPVOID) NULL, /* pass thread index as */ /* function argument */ CREATE_SUSPENDED, /* create suspended */ &IDThread ); /* returns thread id */ /* Check the return value for success. */ if( hThread == NULL ) { /* error creating thread */ Fail( "ERROR:%lu:CreateThread call failed\n", GetLastError() ); } /* Resume the suspended thread */ ResumeThread( hThread ); /* wait on the other thread to complete */ ret = WaitForSingleObject( hThread, INFINITE ); if( ret != WAIT_OBJECT_0 ) { Trace( "ERROR:WaitForSingleObject() returned %lu, " "expected WAIT_OBJECT_0\n", ret ); if( ! CloseHandle( hThread ) ) { Trace( "ERROR:%lu:CloseHandle() call failed\n", GetLastError() ); } Fail( "test failed\n" ); } /* queue our APC on the finished thread */ ret = QueueUserAPC( APCFunc, hThread, 0 ); if( ret != 0 ) { Trace( "ERROR:QueueUserAPC call succeeded on a terminated thread\n" ); if( ! CloseHandle( hThread ) ) { Trace( "ERROR:%lu:CloseHandle() call failed\n", GetLastError() ); } Fail( "test failed\n" ); } if( ! CloseHandle( hThread ) ) { Fail( "ERROR:%lu:CloseHandle() call failed\n", GetLastError() ); } /* dummy check that the APC function wasn't actually executed */ if( bAPCExecuted != FALSE ) { Fail( "ERROR:APC function was executed\n" ); } /* PAL termination */ PAL_Terminate(); /* return success */ return PASS; }
DWORD QueueUserAPCEx(PAPCFUNC pfnApc, HANDLE hThread, DWORD dwData) /* * ------------------------------------------------------ * DOCPUBLIC * Adds a user-mode asynchronous procedure call (APC) object * to the APC queue of the specified thread AND sets this * thread in alertarte state. * * PARAMETERS * Uses the same parameters as QueueUserAPC. * * DESCRIPTION * Adds a user-mode asynchronous procedure call (APC) object * to the APC queue of the specified thread AND sets this * thread in alertarte state. * * RESULTS * 1 Success * 0 Failure * ------------------------------------------------------ */ { DWORD cbReturned; /* trivial case */ if (hThread == GetCurrentThread()) { if (!QueueUserAPC(pfnApc, hThread, dwData)) { return 0; } SleepEx(0, TRUE); return 1; } if (INVALID_HANDLE_VALUE == hDevice /* && !QueueUserAPCEx_Init() */ ) { printf ("Can't get a handle to the ALERT driver\n"); return 0; } /* probably not necessary */ if (SuspendThread(hThread) == -1) { return 0; } /* Send the APC */ if (!QueueUserAPC(pfnApc, hThread, dwData)) { return 0; } /* Ensure the execution of the APC */ if (DeviceIoControl (hDevice, (DWORD)IOCTL_ALERTDRV_SET_ALERTABLE2, &hThread, sizeof(HANDLE), NULL, 0, &cbReturned, 0)) { } else { printf ("DeviceIoControl failed\n"); return 0; } /* Here, we could even cancel suspended threads */ ResumeThread(hThread); return 1; }
void vlc_cancel (vlc_thread_t th) { QueueUserAPC (vlc_cancel_self, th->id, (uintptr_t)th); }
void WakeThread(HANDLE hThread) { QueueUserAPC(NullAPC, hThread, 0); }
int CALLBACK wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) { LPWSTR dllName = 0; LPWSTR appName = 0; LPWSTR appArg = 0; int argc = 0; LPWSTR *argv = CommandLineToArgvW(lpCmdLine, &argc); for (int i = 0; i < argc; i++) { if (!_wcsicmp(L"--dll", argv[i])) { i++; dllName = argv[i]; } else if (!_wcsicmp(L"--app", argv[i])) { i++; appName = argv[i]; } else if (!_wcsicmp(L"--arg", argv[i])) { i++; appArg = argv[i]; } else if (!_wcsicmp(L"--help", argv[i])) { MessageBox(NULL, L"DllLoader.exe --dll test.dll --app target.exe --arg \"arg0=123\"", L"Help", 0); return 0; } } if (!dllName || !appName) { MessageBox(NULL, L"--dll and --app can't be empty", L"", 0); return 1; } wchar_t appPath[1024]; wchar_t envPath[512]; wchar_t dllPath[512]; GetModuleFileName(NULL, envPath, sizeof(envPath) / sizeof(envPath[0])); memcpy(appPath, envPath, sizeof(envPath)); memcpy(dllPath, envPath, sizeof(envPath)); wchar_t *e = wcsrchr(envPath, L'\\'); e[0] = 0x00; wcscpy(e + 1 - envPath + dllPath, dllName); if (appArg) swprintf(e + 1 - envPath + appPath, 512, L"%s %s", appName, appArg); else wcscpy(e + 1 - envPath + appPath, appName); STARTUPINFOW si; PROCESS_INFORMATION pi; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); ZeroMemory(&pi, sizeof(pi)); if (!CreateProcess(NULL, appPath, 0, 0, 0, CREATE_SUSPENDED, 0, envPath, &si, &pi)) { MessageBox(NULL, L"can't create process!", L"", 0); return 1; } LPVOID libArg = VirtualAllocEx(pi.hProcess, 0, sizeof(dllPath), MEM_COMMIT, PAGE_READWRITE); WriteProcessMemory(pi.hProcess, libArg, dllPath, sizeof(dllPath), 0); QueueUserAPC((PAPCFUNC)&LoadLibrary, pi.hThread, (ULONG_PTR)libArg); ResumeThread(pi.hThread); CloseHandle(pi.hThread); LocalFree(argv); //WaitForSingleObject(pi.hProcess, -1); CloseHandle(pi.hProcess); return 0; }