I have a bluetooth serial port to communicate with hardwares. If the hardware does not power on, using "CreateFile" will make thread blocked and cause a error "The semaphore timeout period has expired" after 5-6 seconds. Is it possible to spend less time getting the result of using "CreateFile" by setting timeout-time ? Thank you.
unfortunately CreateFile is synchronous only api which not take any timeout parameter (even low level ZwCreateFile not have this functional).
maximum what you can do in this case - move call CreateFile to separate thread, and if after some time it not finished - call CancelSynchronousIo for this thread. this can help but only can - I/O Completion/Cancellation Guidelines
All IRPs (including Create) that can take an indefinite amount of time must be able to be cancelled
but I/O Subsystem Depends on Drivers - so result will be depended - are driver which handle serial port implement cancelation of IRP_MJ_CREATE
struct OPEN_PACKET
{
PCWSTR lpFileName;
HANDLE hFile;
DWORD error;
DWORD dwDesiredAccess;
DWORD dwShareMode;
DWORD dwCreationDisposition;
DWORD dwFlagsAndAttributes;
};
DWORD WINAPI OpenComPort(OPEN_PACKET* op)
{
HANDLE hFile = CreateFile(op->lpFileName, op->dwDesiredAccess, op->dwShareMode,
NULL, op->dwCreationDisposition,op->dwFlagsAndAttributes, NULL);
op->error = hFile == INVALID_HANDLE_VALUE ? GetLastError() : NOERROR;
op->hFile = hFile;
return GetLastError();// for possible use GetExitCodeThread but use op->error better
}
void testCC(PCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes)
{
OPEN_PACKET op = { lpFileName, INVALID_HANDLE_VALUE, ERROR_IO_PENDING,
dwDesiredAccess, dwShareMode, dwCreationDisposition, dwFlagsAndAttributes };
ULONG ticks = GetTickCount();
if (HANDLE hThread = CreateThread(NULL, PAGE_SIZE, (PTHREAD_START_ROUTINE)OpenComPort, &op, 0, NULL))
{
if (WaitForSingleObject(hThread, 1000) == WAIT_TIMEOUT)//1 sec for example
{
CancelSynchronousIo(hThread);
WaitForSingleObject(hThread, INFINITE);
}
CloseHandle(hThread);
}
else
{
op.error = GetLastError();
}
ticks = GetTickCount() - ticks;
WCHAR sz[256];
if (!FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, op.error, 0, sz, RTL_NUMBER_OF(sz), NULL)) *sz = 0;
DbgPrint("[%u ms] hFile=%p err=%u %S\n", ticks, op.hFile, op.error, sz);
if (op.hFile != INVALID_HANDLE_VALUE)
{
CloseHandle(op.hFile);
}
}
void ep()
{
testCC(L"\\\\server\\share\\1.txt", FILE_GENERIC_READ|FILE_GENERIC_WRITE, FILE_SHARE_VALID_FLAGS, OPEN_EXISTING, 0);
testCC(L"\\\\?\\globalroot\\systemroot\\notepad.exe", FILE_GENERIC_READ|FILE_GENERIC_WRITE, FILE_SHARE_VALID_FLAGS, OPEN_EXISTING, 0);
testCC(L"\\\\?\\globalroot\\systemroot\\notepad.exe", FILE_GENERIC_READ, FILE_SHARE_VALID_FLAGS, OPEN_EXISTING, 0);
}
and I get the next results:
[1000 ms] hFile=FFFFFFFFFFFFFFFF err=995 The I/O operation has been aborted because of either a thread exit or an application request.
[0 ms] hFile=FFFFFFFFFFFFFFFF err=5 Access is denied.
[0 ms] hFile=0000000000000154 err=0 The operation completed successfully.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With