C++, Get handle to open process - c++

I'm trying to get a handle to my open processes, this is what I've got:
#include "stdafx.h"
#include <Psapi.h>
using namespace std;
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR pCmdLine, int iCmdShow)
{
bool _result;
DWORD *pProcessIds = new DWORD[1000];
DWORD cb;
DWORD *pBytesReturned= new DWORD[1000];
_result = EnumProcesses(pProcessIds, 1000,pBytesReturned);
HANDLE _Proccess = new HANDLE;
for (int i = 0;i<=1000; i++)
{
_Proccess = OpenProcess(READ_CONTROL, false, *pProcessIds);
DWORD error;
error = GetLastError();
CloseHandle(_Proccess);
pProcessIds ++;
}
return 0;
}
1- I am constanly getting error "87".
2- _Proccess isn't being assigned anything either. On every itertaion its being set at "0x00000000".
3- EnumProcess is working correctly because pBytesReturned returns a number.
Any Ideas?

Make sure you run as administrator
for (int i = 0;i<=1000; i++)
is wrong because you are missing the last iteration, change <= to <
DWORD *pBytesReturned= new DWORD[1000];
This can just be DWORD bytesToReturn instead of this dynamic array because you only need an integer return.
EnumProcesses(pProcessIds, 1000,pBytesReturned);
Instead of hardcoding 1000, use sizeof(array)
MSDN has a tutorial on how to do this properly.
I modified the code to do what you want it to do and tested it working:
int main(void)
{
DWORD aProcesses[1024], cbNeeded, cProcesses;
unsigned int i;
if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded))
{
return 1;
}
// Calculate how many process identifiers were returned.
cProcesses = cbNeeded / sizeof(DWORD);
// Print the name and process identifier for each process.
for (i = 0; i < cProcesses; i++)
{
if (aProcesses[i] != 0)
{
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, false, aProcesses[i]);
CloseHandle(hProc);
}
}
return 0;
}

Related

C++ Win API - FindWindow() or EnumWindows() to retrieve specific windows

I have the following problem with retrieving the window handle from a specific window (title and class name are known):
There are two identical windows with different handles under two different processes, but FindWindow() can find the handle only from the newest window spawned, never from the first one.
What can be used instead? Can EnumWindows() be used to retrieve a list of windows with the same characteristics?
Use the Win32 API EnumWindows , and then check which process each window belongs to by using the Win32 API GetWindowThreadProcessId.
Here is a sample:
#include <iostream>
#include <Windows.h>
using namespace std;
BOOL CALLBACK enumProc(HWND hwnd, LPARAM) {
TCHAR buf[1024]{};
GetClassName(hwnd, buf, 100);
if (!lstrcmp(buf, L"Notepad"))
{
GetWindowText(hwnd, buf, 100);
DWORD pid = 0;
GetWindowThreadProcessId(hwnd, &pid);
wcout << buf << " " << pid << endl;
}
return TRUE;
}
int main() {
EnumWindows(&enumProc, 0);
}
If you need to check the window of each process, you can refer to this answer.
typedef struct
{
const char *name;
const char *class;
HWND handles[10];
int handlesFound;
} SearchWindowInfo;
SearchWindowInfo wi;
wi.handlesFound = 0;
wi.title = "WindowName";
wi.class = "ClassName";
BOOL CALLBACK searchWindowCallback(HWND hwnd, LPARAM lParam)
{
SearchWindoInfo *wi = (SearchWindoInfo *)lParam;
char buffer[256];
if (wi->handlesFound == 10)
return FALSE;
buffer[255] = 0;
if (wi->name)
{
int rc = GetWindowText(hwnd, buffer, sizeof(buffer)-1);
if(rc)
{
if (strcmp(wi->name, buffer) == 0)
{
wi->handles[wi->handlesFound++] = hwnd;
return TRUE;
}
}
}
if (wi->class)
{
int rc = GetClassName (hwnd, buffer, sizeof(buffer)-1);
if(rc)
{
if (strcmp(wi->class, buffer) == 0)
{
wi->handles[wi->handlesFound++] = hwnd;
return TRUE;
}
}
}
return TRUE;
}
EnumWindows(searchWindowCallback, (LPARAM)&wi);
for(int i = 0; i < wi.handlesFound; i++)
{
// yeah...
}

C++ _tWinMain run more than one times?

Im using DuiLib and Cef.
and I fond that my _tWinMain called 2 times.
1:When I open app,main() was called;
2 When I Create a Window, main() was called 2nd.
here is some code:
vector<wstring> StartArgs;
map<wstring, wstring> argsMaps;
void GetArgMap() {
for (int i = 1; i < StartArgs.size(); ++i) {
wstring argStr = StartArgs[i];
vector<wstring> argVec;
split(argStr, L':', argVec);
if (argVec.size() >= 2) {
wstring k = argVec[0];
wstring v = argVec[1];
argsMaps.insert(map<wstring, wstring>::value_type(k,v));
}
}
}
wstring GetArgForKey(wstring key) {
wstring ret = argsMaps[key];
if (lstrcmpW(ret.c_str(), L"")) {
return ret;
}
else {
return L"null";
}
}
bool CheckParamAvialble(wstring param) {
if (lstrcmpW(param.c_str(), L"null")) {
return true;
}
else {
return false;
}
}
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine,
int nCmdShow)
{
ShowMessageBox(L"this is test alert!", L"WARNING");
int argCount = 0;
LPWSTR cmdline = GetCommandLine();
//cmdline is [m:1 h:0 a:500000 n:xxx c:xxx u:usera o:TOKEN]
LPWSTR* szArgList = CommandLineToArgvW(cmdline, &argCount);
for (int i = 0; i < argCount; ++i) {
wstring a = szArgList[i];
StartArgs.push_back(a);
}
if (argCount >= 7) {
wstring mString = GetArgForKey(L"m");
if (!CheckParamAvialble(mString))
{
ShowMessageBox(L"arg m is wrong!", L"Error");
return 0;
}
/*
do something with other args
*/
CPaintManagerUI::SetInstance(hInstance);
InitResource();
HRESULT Hr = ::CoInitialize(NULL);
if (FAILED(Hr)) return 0;
CefMainArgs args(hInstance);
CefRefPtr<SimpleApp> app(new SimpleApp);
int exitCode = CefExecuteProcess(args, app, NULL);
if (exitCode >= 0)
{
return exitCode;
}
CefSettings settings;
CefInitialize(args, settings, app.get(), NULL);
CefRefPtr<CefCommandLine> command_line;
command_line = CefCommandLine::CreateCommandLine();
command_line->AppendSwitch("no-proxy-server");
MainForm *pFrame = new MainForm(_T("Forms\\MA_MainForm.xml"));
if (pFrame == NULL) return 0;
pFrame->Create(NULL, _T("MainForm"), UI_WNDSTYLE_FRAME, WS_EX_STATICEDGE | WS_EX_APPWINDOW, 0, 0, 600, 800);//when progrom go here,i got 2nd MessageBox[this is test alert!]
pFrame->CenterWindow();
CefRunMessageLoop();
CefShutdown();
return 0;
}
else
{
ShowMessageBox(L"something wrong and exit", L"Error");
return 0;
}
}
and the strange thing is
2nd call main() wont trigger my break point, it just show messagebox[this is test alert!] again.
and if i show another window, it will show 3rd messagebox[this is test alert!]
just show the messagebox multiple times,no break,no exception.
thanks a lot.
Have you read over how the Chromium Embedded Framework works? It will create multiple processes, normally by spawning additional copies of the main executable. When that happens, you'll get a different process displaying your "this is a test alert" dialog. Since this is a different process, your breakpoints will not be hit unless you have your debugger configured to debug any spawned child processes.
The result is that what you see is the expected behavior.

DirectInput8 Hooking Issue

I'm just beginning with directx/directinput development and I'm running some tests with some code samples I've found online. Anyway, I want to hook an application that uses dinput8 to send my own custom input to the forewindow and I'm working with this base to do it:
// dllmain.cpp : Defines the entry point for the DLL application.
#define _CRT_SECURE_NO_WARNINGS // ignore some warnings...
#define _CRT_NON_CONFORMING_SWPRINTFS // ...
#include "stdio.h"
#include <windows.h>
#include "detours.h"
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
#include <time.h>
#include "dinput.h"
#pragma comment(lib, "detours.lib")
#pragma comment(lib, "user32.lib")
typedef HRESULT(__stdcall* GetDeviceState_t)(LPDIRECTINPUTDEVICE, DWORD, LPVOID *);
HRESULT __stdcall hkGetDeviceState(LPDIRECTINPUTDEVICE pDevice, DWORD cbData, LPVOID *lpvData);
DWORD Base = 0;
DWORD GetDeviceStateOffset = 0x7670; // This is the offset of GetDeviceState from DInput8.dll
// Open IDA and Import the DInput8.dll, then look in the Functions Table for DirectInput8Create
// There is an Address (1000XXXX or 0CXXXXX) - copy it and save it for later
// Then take a look for CDIDev_GetDeviceState and copy that address too
// Now substract the Address from CDIDev_GetDeviceState from DIrectInput8Create and u'll get your offset
HANDLE tmpHandle = NULL;
HMODULE hModDInput8 = NULL;
DWORD dwGetDeviceState = NULL;
FARPROC dwDirectInput8Create = NULL;
struct MyKeys
{
BYTE Key;
DWORD StartTime;
DWORD TTL;
BOOLEAN isDown;
};
MyKeys KeyBuffer[256];
DWORD WINAPI HookThread();
void add_log(char* format, ...);
void SendKeyDInput(byte DIK_, DWORD time);
GetDeviceState_t pGetDeviceState;
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
add_log("==========LOG START==========");
add_log("DLL Attached");
add_log("Creating Thread...");
tmpHandle = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)&HookThread, 0, 0, 0);
if (!tmpHandle)
{
add_log("ThreadCreation Failed!");
}
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
DWORD WINAPI HookThread()
{
Base = (DWORD)GetModuleHandleA("test.exe");
add_log("Thread Created");
add_log("game.exe Base: %x", Base);
while (!hModDInput8)
{
add_log("Searching dinput8.dll...");
hModDInput8 = GetModuleHandle(L"dinput8.dll");
Sleep(100);
}
add_log("Found dinput8.dll: %x !", hModDInput8);
while (!dwDirectInput8Create)
{
add_log("Searching GetDeviceState...");
dwDirectInput8Create = GetProcAddress(hModDInput8, "DirectInput8Create");
Sleep(100);
}
add_log("Found DirectInput8Create: %x !", dwDirectInput8Create);
dwGetDeviceState = (DWORD)((DWORD)dwDirectInput8Create - GetDeviceStateOffset);
add_log("GetDevicestate is here (DirectInput8Create - %x): %x", GetDeviceStateOffset, dwGetDeviceState);
add_log("Hooking GetDeviceState...");
pGetDeviceState = (GetDeviceState_t)DetourAttach(&(PVOID&)dwGetDeviceState, (PBYTE)hkGetDeviceState);
add_log("Initiate Keyboard Buffer...");
//initiate buffer
for (int i = 0; i < 256; i++)
{
KeyBuffer[i].isDown = false;
KeyBuffer[i].Key = 0;
KeyBuffer[i].StartTime = 0;
KeyBuffer[i].TTL = 0;
}
add_log("Going into Main Loop...");
while (true)
{
if (GetAsyncKeyState(VK_F5) & 1 << 15)
{
// We check the Most Sigificant Bit from VK_F5 (F5) whilst we shifted it with 15 bits to left 1
// and then a small delay so we have enaught time to release the key
add_log("F5 pushed attempting to sendkey");
// Sleep a short time so we have time to release the F5 Key
Sleep(500);
// Now we send a A Key with 1 sec time to our Game
SendKeyDInput(DIK_A, 1000);
}
}
return 0;
}
void SendKeyDInput(byte DIK, DWORD time)
{
KeyBuffer[DIK].Key = DIK;
KeyBuffer[DIK].TTL = time;
KeyBuffer[DIK].StartTime = GetTickCount();
}
HRESULT __stdcall hkGetDeviceState(LPDIRECTINPUTDEVICE lpDevice, DWORD cbData, LPVOID *lpvData)
{
HRESULT hResult = DI_OK;
static BYTE buffer[256];
int key_count = 0;
for (int i = 0; i<256; i++)
{
if (KeyBuffer[i].Key != 0 && KeyBuffer[i].TTL>0 && KeyBuffer[i].StartTime != 0)
{
if (GetTickCount() > KeyBuffer[i].StartTime + KeyBuffer[i].TTL && KeyBuffer[i].isDown)
{
KeyBuffer[i].Key = 0;
KeyBuffer[i].StartTime = 0;
KeyBuffer[i].TTL = 0;
KeyBuffer[i].isDown = false;
buffer[KeyBuffer[i].Key] = 0;
}
else {
KeyBuffer[i].isDown = true;
buffer[KeyBuffer[i].Key] = 0x80;
key_count += 1;
add_log("Sending Key %x for %i milliseconds count: %i", KeyBuffer[i].Key, KeyBuffer[i].TTL, key_count);
}
}
}
if (key_count != 0)
{
cbData = 256;
memcpy(lpvData, buffer, cbData);
}
else {
hResult = pGetDeviceState(lpDevice, cbData, lpvData);
}
return hResult;
}
//Creates a Logfile in the Game Directory
void add_log(char* format, ...)
{
HANDLE filehandle;
DWORD dwReadBytes;
char buffer[2048];
char writebuffer[2048];
va_list args;
va_start(args, format);
vsprintf_s(buffer, format, args);
filehandle = CreateFile(L"Log.txt", GENERIC_WRITE, 0, 0, OPEN_ALWAYS, 0, 0);
SetFilePointer(filehandle, 0, 0, FILE_END);
sprintf_s(writebuffer, 2048, "Log Added: %s\r\n", buffer);
WriteFile(filehandle, writebuffer, strlen(writebuffer), &dwReadBytes, 0);
CloseHandle(filehandle);
}
The only issue in this code is when I attempt to send input, it doesn't go through. I've gotten some help and narrowed down a solution to this, which was: "Try GetDeviceState hk just memset(buffer, 0, size) or SendDeviceData". I've searched around a bit and I've been unable to find more on how to implement this solution and I'm stumped.
Could one of you kind people show me how I could use this information to fix this base? I'd be extremely grateful, thanks.

WinApi Thread (Pointer error)

I have a probelm :( i wanna make a program wich gives a random number :) i don't want use rand() function :) i wanna make one for me then turn it to a function ;) for educational purpose :)
but i have a problem :( see my code :)
#include <stdio.h>
#include <iostream>
#include <conio.h>
#include <windows.h>
#define MIN 0
#define MAX 99999
using namespace std;
typedef struct _RANDOM_INFO{
DWORD random;
DWORD min;
DWORD max;
} RANDOM_INFO, * LPRANDOM_INFO;
void Error(LPSTR lpErrorMessage){
cout << lpErrorMessage << endl;
exit(EXIT_FAILURE);
}
void GetRandom(LPVOID lpParam){
DWORD dwListSize = 10000, min = 0, max = 99999;
LPDWORD lpRandom = (LPDWORD)lpParam;
LPSTR lpFileSelf, lpKernel, lpNtdll;
HMODULE hFileSelf = NULL, hKernel = NULL, hNtdll = NULL;
hFileSelf = (HMODULE) GetModuleHandle(NULL);
hKernel = (HMODULE) GetModuleHandle("kernel.dll");
hNtdll = (HMODULE) GetModuleHandle("ntdll.dll");
lpFileSelf = (LPSTR) hFileSelf;
lpKernel = (LPSTR) hKernel;
lpNtdll = (LPSTR) hNtdll;
while(1){
DWORD i;
for(i = 0; i <= dwListSize; i++){
*lpRandom = (DWORD)lpFileSelf[i];
}
i = 0;
}
return;
}
int main(int argc, char **argv)
{
DWORD random = 0;
DWORD getRandomThreadId = 0;
HANDLE hGetRandomThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)GetRandom, &random, 0, &getRandomThreadId);
if(hGetRandomThread == INVALID_HANDLE_VALUE)
Error("Cannot make a random list.");
getch();
cout << random << endl;
Sleep(1500);
return 0;
}
The variable should get a value when and print it but i always i get 0 and a windows error can someone tell me why??? and another problem when i try to use the variable hKernel in the GetRandom function i get an error too :( but it works fine whith hFileSelf and hNtdll !!!! is kernel protected from reading???
Note : this is not a random number generation :) its just a way to get a number from the memory when the user click on the enter on his keyboard :), and its not always the same time for all users so its not always the same pointer in memory :) i hope u understand what i want do :) sorry for my bad englush :) just help me to fix the problem :)
Thank u :)
Your GetRandom() function does not have the correct signature for a CreateThread() callback procedure. Try this instead:
#include <stdio.h>
#include <iostream>
#include <conio.h>
#include <windows.h>
#define MIN 0
#define MAX 99999
using namespace std;
typedef struct _RANDOM_INFO
{
DWORD random;
DWORD min;
DWORD max;
} RANDOM_INFO, * LPRANDOM_INFO;
void Error(LPSTR lpErrorMessage)
{
cout << lpErrorMessage << endl;
exit(EXIT_FAILURE);
}
HMODULE hFileSelf = (HMODULE) GetModuleHandle(NULL);
DWORD WINAPI GetRandomThreadProc(LPVOID lpParam)
{
LPDWORD lpRandom = (LPDWORD) lpParam;
DWORD dwListSize = 10000, min = 0, max = 99999;
LPBYTE lpFileSelf = (LPBYTE) hFileSelf;
while (1)
{
for (DWORD i = 0; i <= dwListSize; ++i)
{
*lpRandom = (DWORD) lpFileSelf[i];
}
Sleep(0);
}
return 0;
}
int main(int argc, char **argv)
{
DWORD dwRandom = 0;
DWORD dwRandomThreadId = 0;
HANDLE hGetRandomThread = CreateThread(NULL, 0, &GetRandomThreadProc, &dwRandom, 0, &dwRandomThreadId);
if (hGetRandomThread == INVALID_HANDLE_VALUE)
Error("Cannot make a random list.");
do
{
getch();
cout << dwRandom << endl;
}
while (WaitForSingleObject(hGetRandomThread, 0) == WAIT_TIMEOUT);
CloseHandle(hGetRandomThread);
return 0;
}
i wanna make a program wich gives a random number
What you are doing has nothing to do with random number generation.
This is one way to do it:
Linear Congruential Generator

Create multiple files using multi threading in C++ using Win32 API

I am trying to create files in a pen drive. If the pen drive is not present, threads should suspend. When it is inserted it should resume. Here is the code I tried but it's not working properly. Can any one help me?
#include "stdafx.h"
#include <Windows.h>
#include <Strsafe.h>
#include <WinBase.h>
LPCTSTR Disk=L"E:\";
LPTSTR drive_Name=L"E:\\demo";
CRITICAL_SECTION section;
#define BUFFER_SIZE 1024
#define count 10
HANDLE Write_Handle[10],Open_Handle[10],read_Handle[10] ;
DWORD WINAPI check_Thread(LPVOID lpParameter)
{
int *nThreadNo = (int*)lpParameter;
while(1)
{
if(GetDiskFreeSpaceExW(Disk,NULL,NULL,NULL))
{
ResumeThread(Write_Handle[*nThreadNo]);
ResumeThread(read_Handle[*nThreadNo]);
}
else
{
SuspendThread(Write_Handle[*nThreadNo]);
SuspendThread(read_Handle[*nThreadNo]);
}
}
}
DWORD WINAPI Write_Thread(LPVOID lpParameter)
{
DWORD g_tid = GetCurrentThreadId();
_tprintf(_T(" write thread id %d\n"),g_tid);
LPCWSTR filename=(LPCWSTR)lpParameter;
HANDLE ofile;
EnterCriticalSection(&section);
ofile=CreateFileW(filename,GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_ALWAYS,NULL, NULL);
int d;
d=GetLastError();
if(ERROR_SUCCESS!=GetLastError())
{
_tprintf(_T("error values in open thread %d \n"),GetLastError());
_tprintf(_T("filename %s \n"),filename);
}
const int filesizeinKB = 1024;
BOOL bError;
DWORD dwBytesWritten=0;
WCHAR ReadBuffer[BUFFER_SIZE] = {0};
int i;
for(i = 0; i <= BUFFER_SIZE; i++)
{
ReadBuffer[i] = (char)(i%26 + 'a');
}
for (i = 0; i <= filesizeinKB; i++)
{
SetLastError(0);
bError= WriteFile(ofile, ReadBuffer-1, BUFFER_SIZE,&dwBytesWritten, NULL);
bError=GetLastError();
if (ERROR_SUCCESS!=GetLastError())
{ _tprintf(_T("error value in write %d\n"),GetLastError());
_tprintf(_T(" Write Error...\n"));
return 1;
}
}
SetLastError(0);
CloseHandle(ofile);
_tprintf(_T("write close error values %d\n"),GetLastError());
LeaveCriticalSection(&section);
return 1;
}
DWORD WINAPI Read_Thread(LPVOID lpParameter)
{
HANDLE ofile;
DWORD g_tid = GetCurrentThreadId();
_tprintf(_T(" write thread id %d\n"),g_tid);
LPCWSTR filename=(LPCWSTR)lpParameter;
EnterCriticalSection(&section);
ofile=CreateFileW(filename,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_ALWAYS,NULL, NULL);
int d;
d=GetLastError();
if(ERROR_SUCCESS!=GetLastError())
{
_tprintf(_T("error values in open thread %d \n"),GetLastError());
_tprintf(_T("filename %s \n"),filename);
}
DWORD dwBytesRead=0;
WCHAR ReadBuffer[BUFFER_SIZE] = {0};
_tprintf(_T(" read thread \n"));
SetLastError(0);
int err;
ReadFile(ofile, ReadBuffer, (BUFFER_SIZE-1), &dwBytesRead, NULL);
err=GetLastError();
_tprintf(_T("read error values %d \n"),GetLastError());
if(ERROR_SUCCESS!=GetLastError())
{
_tprintf(L"reading failed \n");
return 0;
}
SetLastError(0);
CloseHandle(ofile);
err=GetLastError();
_tprintf(_T("close error values %d\n"),GetLastError());
LeaveCriticalSection(&section);
return 1;
}
int _tmain(int argc, _TCHAR* argv[])
{
unsigned int myCounter = 0;
DWORD WritethreadID,OpenThreadID,ReadthreadID;
HANDLE check_Handle;
DWORD exThread;
TCHAR filename[100];
HANDLE hfile;
INT bsize=100;
int i=0;
InitializeCriticalSection (&section);
CreateDirectory(drive_Name,NULL);
for(i=0;i<5;i++)
{
SetLastError(0);
StringCchPrintf(filename,bsize, TEXT("%s\\file_%d.txt"),drive_Name,i );
hfile=CreateFileW(filename,GENERIC_WRITE|GENERIC_READ,NULL,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
if (hfile == INVALID_HANDLE_VALUE)
{
_tprintf(_T("invalid handle \n" ));
}
_tprintf(_T("file created %s\n"),filename);
CloseHandle(hfile);
Write_Handle[i] =CreateThread(0, 0, Write_Thread, filename, CREATE_SUSPENDED, &WritethreadID);
SetThreadPriority(Write_Handle[i],2);
_tprintf(_T("write thread id is %d\n"),WritethreadID);
read_Handle[i]=CreateThread(0, 0, Read_Thread, filename, CREATE_SUSPENDED, &ReadthreadID);
SetThreadPriority(read_Handle[i],1);
_tprintf(_T("read thread id is %d\n "),ReadthreadID);
check_Handle =CreateThread(0, 0, check_Thread,(void*)&i ,0,&OpenThreadID);
}
for (i=0; i<count; ++i)
{
WaitForSingleObject(Write_Handle[i],INFINITE);
if ( !GetExitCodeThread(Write_Handle, &exThread) )
{
_tprintf(_T("close thread %08X\n"),GetLastError());
}
SetLastError(0);
CloseHandle(Write_Handle[i]);
_tprintf(_T("close thread %08X\n"),GetLastError());
WaitForSingleObject(read_Handle[i],INFINITE);
if ( !GetExitCodeThread(read_Handle, &exThread) )
{
_tprintf(_T("GetExitCodeThread %08X\n"),GetLastError());
}
SetLastError(0);
CloseHandle(read_Handle[i]);
_tprintf(_T("GetExitCodeThread %08X\n"),GetLastError());
CloseHandle(check_Thread);
}
DeleteCriticalSection(&section);
return 1;
}
If you have open file handles to a USB drive when that drive is removed, those file handles will become invalid. Reinserting the USB drive will not reconstitute those handles in such a way that you can continue after resuming a thread.
You will need to:
detect when the device is removed, and close those now-broken handles
when the device is inserted, open the files again and continue whatever you were doing
Your error handlers are returning without calling LeaveCriticalSection, leaving the CS locked and blocking the other threads indefinitely. From the EnterCriticalSection docs:
If a thread terminates while it has ownership of a critical section,
the state of the critical section is undefined.
Those cases also leave the file handles open.