LockFile() does not have waiting timeout, LockFileEx() does not, either.
If I want to wait for file-lock with timeout, how would I go about it?
That is, how do I implement the following:
DWORD LockFileTimed(HANDLE h,
DWORD milli,
__in DWORD dwFileOffsetLow,
__in DWORD dwFileOffsetHigh,
__in DWORD nNumberOfBytesToLockLow,
__in DWORD nNumberOfBytesToLockHigh)
I understand your intention of LockFileTimed as it will not return immediately when the file cannot be locked, but retry to lock the file for the given time. Is it right? It's unclear whether this is what you want.
A simple way to implement would be just writing a small loop to check the return code.
DWORD timer_end = GetTickCount() + milli;
while (GetTickCount() < timer_end) {
if (LockFile(...))
return TRUE;
else
Sleep(0); // Wait sometime.
}
return FALSE;
Related
I'm trying to implement an injection of my 64-bit DLL into a 64-bit process. My host process calls CreateRemoteThread with a thread subroutine pointing to LoadLibrary. The DLL later unloads itself "from within" by calling FreeLibraryAndExitThread.
My goal is to know if the injected LoadLibrary call succeeded. For that unfortunately I can't use GetExitCodeThread from within my (host) process since returned 64-bit HMODULE handle is truncated to by a remote thread to DWORD. And I don't want to use Tool Help APIs as they will introduce a race condition.
So thus I was wondering about the lower 32-bits of the HMODULE returned by LoadLibrary in a 64-bit process -- can I reliably assume that its lower 32-bits will not be 0's for a valid handle?
PS. I don't need the HMODULE handle itself, all I need to know if LoadLibrary succeeded or not.
Edit. The call from my host process is done as such (in a very concise pseudo-code -- no error checking):
CreateRemoteThread(hProcess, 0, 0,
GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryW"),
pVmAddressOfMyDllsPathWrittenWith_WriteProcessMemory, 0, 0);
Can I reliably assume that its lower 32-bits will not be 0's for a valid handle?
No you cannot. An HMODULE is just the same in 64 bit as it is in 32 bit. It is the base address of the loaded module. So there is no reason why a valid HMODULE would have to have non-zero low order bits.
It's very simple for you to confirm this. Create a 64 bit DLL with an IMAGEBASE set to, for instance, 0x0000000100000000. Load that DLL, and inspect the value of the returned HMODULE.
instead CreateRemoteThread with a thread subroutine pointing to LoadLibraryW we can inject tiny shell code to remote process which first call LoadLibraryW and than, if it fail, GetLastError - as result remote thread return error code (0 if no error) - and you will be know exactly - are LoadLibrary ok and if not - have error code. the 64 asm code can be:
CONST segment
SHELLDATA struct
LoadLibrary DQ ?
GetLastError DQ ?
SHELLDATA ends
public RemoteThreadProc_begin
public RemoteThreadProc_end
RemoteThreadProc_begin:
RemoteThreadProc proc
nop
nop
nop
call ##0
___ SHELLDATA <>
##0:
xchg [rsp],rbp
sub rsp,20h
call SHELLDATA.LoadLibrary[rbp]
test rax,rax
jz ##1
xor eax,eax
##2:
add rsp,20h
pop rbp
ret
##1:
call SHELLDATA.GetLastError[rbp]
jmp ##2
RemoteThreadProc endp
RemoteThreadProc_end:
CONST ends
and c++ code:
extern "C"
{
extern UCHAR RemoteThreadProc_begin[], RemoteThreadProc_end[];
}
enum INJECT_PHASE {
fOpenProcess, fVirtualAlloc, fWriteProcessMemory, fCreateRemoteThread, fMax
};
ULONG injectDll(ULONG dwprocessId, PCWSTR dllFilePath, INJECT_PHASE& phase)
{
ULONG err = 0;
struct SHELLDATA
{
__int64 code;
PVOID LoadLibrary, GetLastError;
};
if (HANDLE hProcess = OpenProcess(PROCESS_CREATE_THREAD|PROCESS_VM_OPERATION|PROCESS_VM_WRITE, FALSE, dwprocessId))
{
SIZE_T cbStr = (wcslen(dllFilePath) + 1) * sizeof(WCHAR);
SIZE_T cbCode = ((RemoteThreadProc_end - RemoteThreadProc_begin) + sizeof(WCHAR) - 1) & ~(sizeof(WCHAR) - 1);
union {
PVOID RemoteAddress;
PBYTE pbRemote;
PTHREAD_START_ROUTINE lpStartAddress;
};
if (RemoteAddress = VirtualAllocEx(hProcess, 0, cbStr + cbCode, MEM_COMMIT, PAGE_EXECUTE_READWRITE))
{
union {
PVOID pv;
PBYTE pb;
SHELLDATA* ps;
};
pv = alloca(cbStr + cbCode);
memcpy(pv, RemoteThreadProc_begin, cbCode);
memcpy(pb + cbCode, dllFilePath, cbStr);
HMODULE hmod = GetModuleHandle(L"kernel32");
ps->GetLastError = GetProcAddress(hmod, "GetLastError");
ps->LoadLibrary = GetProcAddress(hmod, "LoadLibraryW");
if (WriteProcessMemory(hProcess, RemoteAddress, pv, cbStr + cbCode, 0))
{
if (HANDLE hThread = CreateRemoteThread(hProcess, 0, 0, lpStartAddress, pbRemote + cbCode, 0, 0))
{
phase = fMax;
WaitForSingleObject(hThread, INFINITE);
GetExitCodeThread(hThread, &err);
CloseHandle(hThread);
}
else
{
phase = fCreateRemoteThread;
err = GetLastError();
}
}
else
{
phase = fWriteProcessMemory;
err = GetLastError();
}
VirtualFreeEx(hProcess, RemoteAddress, 0, MEM_RELEASE);
}
else
{
phase = fVirtualAlloc;
err = GetLastError();
}
CloseHandle(hProcess);
}
else
{
phase = fOpenProcess;
err = GetLastError();
}
return err;
}
I have a test that creates a series of folders in a loop until it exceeds the MAX_PATH (260). This returns ERROR_PATH_NOT_FOUND(0x3). We have a build machine that runs this test but on the build machine it returns ERROR_FILENAME_EXCED_RANGE (0xce).
My machine is Windows 7 but the build machine is Vista. Could that be why they return different values? If not, does anyone know why this might happen?
EDIT: I am expecting to get an error, im testing a file system driver. I just do not understand why i am getting two different error codes from the same test on different machines.
Here is the code
homeDir << "C:\Users\me\TestFolder";
string childDir = "\\LongChildDirectoryName";
string dir = homeDir.str();
DWORD lastErr = ERROR_SUCCESS;
while(lastErr == ERROR_SUCCESS)
{
int len = dir.size();
if(len > (MAX_PATH - 12))
{
CuFail(tc, "Filepath greater than max allowed should be");
}
dir += childDir;
if(!CreateDirectory(dir.c_str(), NULL))
{
lastErr = GetLastError();
if (lastErr == ERROR_ALREADY_EXISTS)
lastErr = ERROR_SUCCESS;
}
}
CuAssert(tc, "Check error is ERROR_PATH_NOT_FOUND", lastErr == ERROR_PATH_NOT_FOUND);
The logic is flawed. If homeDir.str() returns a name that doesn't exist, the return value from CreateDirectory will be ERROR_PATH_NOT_FOUND. You can demonstrate the problem by simply doing this:
string childDir("\\LongChildDirectoryName");
string dir("foo");
The CreateDirectory call will then get the path foo\LongChildDirectoryName, and if foo doesn't exist, you get ERROR_PATH_NOT_FOUND. The fix is simply to add this before the while loop:
CreateDirectory(dir.c_str(), NULL);
You also need to move the length check after the strings have been concatenated, not before. Using the "\\?\" syntax Alex suggested would also be a good idea.
To use longer paths you need to use the "wide" version of CreateFile(), CreateFileW().
See this MSDN article on the topic:
HANDLE WINAPI CreateFile(
__in LPCTSTR lpFileName,
__in DWORD dwDesiredAccess,
__in DWORD dwShareMode,
__in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes,
__in DWORD dwCreationDisposition,
__in DWORD dwFlagsAndAttributes,
__in_opt HANDLE hTemplateFile
);
lpFileName [in]
The name of the file or device to be created or opened.
In the ANSI version of this function, the name is limited to MAX_PATH characters.
To extend this limit to 32,767 wide characters, call the Unicode version of the
function and prepend "\\?\" to the path. For more information, see Naming Files,
Paths, and Namespaces.
I've been trying to write a program in C++ that will monitor running processes in the background and terminate a certain one if it's detected to be running. I have written a program that will do so, however the only way I can think of to do this is to use an infinite WHILE loop that keeps checking for the program. This, as you can imagine, constantly uses CPU power and resources to be constantly looping. In task manager, you can see that most processes that are running are always using 0% of the CPU. My question is: How can I write or modify this program to run in the background, utilizing 0% of the CPU until it detects the process it's supposed to terminate?
My entire program is below. In this example, I have used "Notepad.exe" in WinMain as the process the program should be terminating.
#include <Windows.h>
#include <iostream>
#include <tlhelp32.h>
#include <string>
#define TA_FAILED 0
#define TA_SUCCESS_CLEAN 1
#define TA_SUCCESS_KILL 2
DWORD WINAPI TerminateApp(DWORD dwPID, DWORD dwTimeout);
DWORD WINAPI Terminate16App(DWORD dwPID, DWORD dwThread, WORD w16Task, DWORD dwTimeout);
typedef struct {
DWORD dwID;
DWORD dwThread;
} TERMINFO;
BOOL CALLBACK TerminateAppEnum( HWND hwnd, LPARAM lParam ) ;
DWORD WINAPI TerminateApp( DWORD dwPID, DWORD dwTimeout ) {
HANDLE hProc ;
DWORD dwRet ;
// If we can't open the process with PROCESS_TERMINATE rights,
// then we give up immediately.
hProc = OpenProcess(SYNCHRONIZE|PROCESS_TERMINATE, FALSE,
dwPID);
if(hProc == NULL) {
return TA_FAILED ;
}
// TerminateAppEnum() posts WM_CLOSE to all windows whose PID
// matches your process's.
EnumWindows((WNDENUMPROC)TerminateAppEnum, (LPARAM) dwPID) ;
// Wait on the handle. If it signals, great. If it times out,
// then you kill it.
if(WaitForSingleObject(hProc, dwTimeout)!=WAIT_OBJECT_0)
dwRet=(TerminateProcess(hProc,0)?TA_SUCCESS_KILL:TA_FAILED);
else
dwRet = TA_SUCCESS_CLEAN ;
CloseHandle(hProc) ;
return dwRet ;
}
BOOL CALLBACK TerminateAppEnum( HWND hwnd, LPARAM lParam ) {
DWORD dwID ;
GetWindowThreadProcessId(hwnd, &dwID) ;
if(dwID == (DWORD)lParam) {
PostMessage(hwnd, WM_CLOSE, 0, 0) ;
}
return TRUE ;
}
DWORD FindProcessId(const std::string& processName);
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) {
std::string process1 = "Notepad.exe";
while (1) {
TerminateApp(FindProcessId(process1),0);
}
return 0;
}
DWORD FindProcessId(const std::string& processName) {
PROCESSENTRY32 processInfo;
processInfo.dwSize = sizeof(processInfo);
HANDLE processesSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
if (processesSnapshot == INVALID_HANDLE_VALUE) {
return 0;
}
Process32First(processesSnapshot, &processInfo);
if (!processName.compare(processInfo.szExeFile)) {
CloseHandle(processesSnapshot);
return processInfo.th32ProcessID;
}
while (Process32Next(processesSnapshot, &processInfo)) {
if (!processName.compare(processInfo.szExeFile)) {
CloseHandle(processesSnapshot);
return processInfo.th32ProcessID;
}
}
CloseHandle(processesSnapshot);
return 0;
}
You can use WMI and event notification to find when processes are created and destroyed. __InstanceCreationEvent is what you need to look for.
Creation of a resource: __InstanceCreationEvent
Suppose you are interested in receiving a notification if Notepad is run on a certain computer. When Notepad runs, a corresponding process is created. Processes can be managed by using WMI and are represented by the Win32_Process class. When Notepad starts running, a corresponding instance of the Win32_Process class becomes available through WMI. If you have registered your interest in this event (by issuing the appropriate event notification query), the availability of this instance results in the creation of an instance of the __InstanceCreationEvent class.
Is it possible to find out to which process a MessageBox belongs? If yes, how?
You want to use GetWindowThreadProcessId. Here is an example.
#include <windows.h>
static const TCHAR g_cszClass = TEXT("#32770"); // dialog box class
// returned handle must be closed with CloseHandle() when no longer used
HANDLE GetMessageBoxProcess(__in_z LPCTSTR lpcszTitle, __in DWORD dwAccess)
{
HWND hWnd;
DWORD dwProcessId = 0;
HANDLE hRET;
hWnd = FindWindow(g_cszClass, lpcszTitle);
if (hWnd != NULL)
{
GetWindowThreadProcessId(hWnd, &dwProcessId);
if (dwProcessId != 0)
hRET = OpenProcess(dwAccess, FALSE, dwProcessId);
}
return hRET;
}
Not sure why you'd want the process though. Reasons I can think of:
terminating the message box completely
detecting a process
detecting a certain message box
all of which have superior & more optimal alternative solutions.
Another answer gives the programmatic solution. If this is a one-off thing for debugging, you can choose the window with Spy++, get the process ID from the properties window, and then look up the process in Task Manager.
It's taken a few years, but I am finally taking the plunge into VC++. I need to be able to read x number of sectors of a physical device (namely a hard drive). I am using the CreateFile() and SetFilePointerEx() and ReadFile() APIs.
I have done a LOT of reading online in all the major forums about this topic. I have exhausted my research and now I feel it's time to ask the experts to weigh in on this dilemma. As this is my very first post ever on this topic, please go easy on my :)
I should also point out that this is a .DLL that I consume with a simple C# app. The plumbing all works fine. It's the SetFilePointer(Ex)() APIs that are causing me grief.
I can get the code to work up until about the size of a LONG (4,xxx,xxx) - I can't remember the exact value. It suffices to say that I can read everything up to and including sector # 4,000,000 but not 5,000,000 or above. The problem lies in the "size" of the parameters for the SetFilePointer() and SetFilePointerEx() APIs. I've tried both and so far, SetFilePointerEx() seems to be what I should use to work on 64-bit systems.
The 2nd and 3rd parameters of the SetFilePointer are defined as follows:
BOOL WINAPI SetFilePointerEx(
__in HANDLE hFile,
__in LARGE_INTEGER liDistanceToMove,
__out_opt PLARGE_INTEGER lpNewFilePointer,
__in DWORD dwMoveMethod
);
Please note that I have tried passing the LowPart and the HighPart as the 2nd and 3 parameters without any success as I get a CANNOT CONVERT LARGE_INTEGER TO PLARGE_INTEGER (for parameter 3).
HERE IS MY CODE. I USE A CODE-BREAK TO VIEW buff[0], etc. I would like to read past the 4,xxx,xxx limitation. Obviously I am doing something wrong. Each read past this limit resets my file pointer to sector 0.
#include "stdafx.h"
#include <windows.h>
#include <conio.h>
extern "C"
__declspec(dllexport) int ReadSectors(long startSector, long numSectors)
{
HANDLE hFile;
const int SECTOR_SIZE = 512;
const int BUFFER_SIZE = 512;
LARGE_INTEGER liDistanceToMove;
PLARGE_INTEGER newFilePtr = NULL; // not used in this context.
// just reading from START to END
liDistanceToMove.QuadPart = startSector * SECTOR_SIZE;
DWORD dwBytesRead, dwPos;
LPCWSTR fname = L"\\\\.\\PHYSICALDRIVE0";
char buff[BUFFER_SIZE];
// Open the PHYSICALDEVICE as a file.
hFile = CreateFile(fname,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
// Here's the API definition
/*BOOL WINAPI SetFilePointerEx(
__in HANDLE hFile,
__in LARGE_INTEGER liDistanceToMove,
__out_opt PLARGE_INTEGER lpNewFilePointer,
__in DWORD dwMoveMethod
);*/
dwPos = SetFilePointerEx(hFile, liDistanceToMove, NULL, FILE_BEGIN);
if(ReadFile(hFile, buff, BUFFER_SIZE, &dwBytesRead, NULL))
{
if(dwBytesRead > 5)
{
BYTE x1 = buff[0];
BYTE x2 = buff[1];
BYTE x3 = buff[2];
BYTE x4 = buff[3];
BYTE x5 = buff[4];
}
}
// Close both files.
CloseHandle(hFile);
return 0;
}
startSector * SECTOR_SIZE;
startSector is a long (32bits), SECTOR_SIZE is a int (also 32bits), multiply these two guys and the intermediate result is going to be a long, which will overflow and you then stuff it into the __int64 of the LARGE_INTEGER, which is too late. You want to operate on __int64s, something like
liDistanceToMove.QuadPart = startSector;
liDistanceToMove.QuadPart *= SECTOR_SIZE;
for example.