I feel like there is an obvious answer to this, but it's been eluding me. I've got some legacy code in C++ here that breaks when it tries to call OpenThread(). I'm running it in Visual C++ 2008 Express Edition. The program first gets the ThreadID of the calling thread, and attempts to open it, like so:
ThreadId threadId = IsThreaded() ? thread_id : ::GetCurrentThreadId();
HANDLE threadHandle = OpenThread(THREAD_ALL_ACCESS, FALSE, threadId);
Now here's what I don't understand: if the thread ID is the current thread's ID, isn't it already open? Could that be why it's returning NULL?
Any feedback would be appreciated.
Maybe you're asking for too much access (THREAD_ALL_ACCESS), though I'd think that you'd have pretty much all permissions to your own thread. Try reducing the access to what you really need.
What does GetLastError() return?
Update:
Take a look at this comment from MSDN:
Windows Server 2003 and Windows
XP/2000: The size of the
THREAD_ALL_ACCESS flag increased on
Windows Server 2008 and Windows Vista.
If an application compiled for Windows
Server 2008 and Windows Vista is run
on Windows Server 2003 or Windows
XP/2000, the THREAD_ALL_ACCESS flag is
too large and the function specifying
this flag fails with
ERROR_ACCESS_DENIED. To avoid this
problem, specify the minimum set of
access rights required for the
operation. If THREAD_ALL_ACCESS must
be used, set _WIN32_WINNT to the
minimum operating system targeted by
your application (for example,
#define _WIN32_WINNT _WIN32_WINNT_WINXP ). For more information, see Using the Windows
Headers
Try using _beginthreadex instead of OpenThread.
Example:
HANDLE hThread;
UINT uiThreadId = 0;
hThread = (HANDLE)_beginthreadex(NULL, // Security attributes
0, // stack
&this->ThreadProc, // Thread proc
this, // Thread param
CREATE_SUSPENDED, // creation mode
&uiThreadId); // Thread ID
if (hThread != NULL){
//SetThreadPriority(hThread, THREAD_PRIORITY_HIGHEST);
ResumeThread(hThread);
m_hThread = hThread;
}
else{
eRetVal = err_ThreadStartErr;
}
Related
I am developing a cross platform platform that is suppose to run on the following platform
Windows x64
Linux x64
Windows ARM
Linux ARM
Android ARM
The program is used in interfacing with multiple Serial Ports (up to 20) and server connectivity using MQTT or ReST-JSON.
I am extensively suing asynchronous operation and threading in my application
I have couple question regarding error handling
Can I handle WIN API error in libc errno integer variable or do I have to use GetLastError in windows and errno in Linux + Android.
Is GetLastError() thread safe?
Is strerror_s thread safe?
Will strerror_s be available in Linux and Android if I select C11 or greater during program build?
My current implementation
//Returns the last error, in string format. Returns an empty string if there is no error.
std::string GetLastErrorAsString(void)
{
#ifdef _WIN64
//Get the error message ID, if any.
DWORD errorMessageID = ::GetLastError();
if (errorMessageID == 0)
{
return std::string(); //No error message has been recorded
}
LPSTR message_buffer = nullptr;
//Ask Win64 to give us the string version of that message ID.
//The parameters we pass in, tell Win64 to create the buffer that holds the message for us (because we don't yet know how long the message string will be).
size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&message_buffer, 0, NULL);
//Copy the error message into a std::string.
std::string error_message(message_buffer, size);
//Free the Win64's string's buffer.
LocalFree(message_buffer);
return error_message;
#elif __linux__ || __ANDROID__
if (errno == 0)
{
return std::string(); //No error message has been recorded
}
size_t error_message_length = strerrorlen_s(errno) + 1;
std::array<char, error_message_length> error_message;
//char errmsg[errmsglen];
strerror_s(error_message.data(), error_message_length, errno);
return std::string(error_message.data());
#endif
}
Can I handle WIN API error in libc errno integer variable or do I have to use GetLastError in windows and errno in Linux + Android.
No, if you are calling Win APIs you will need to use GetLastError() to get the last error.
Is GetLastError() thread safe?
Yes. "Retrieves the calling thread's last-error code value. The last-error code is maintained on a per-thread basis.". Always search MSDN for information about Win API.
Is strerror_s thread safe?
In general, I don't know. A quick search found that it may be on Windows:
https://github.com/MicrosoftDocs/cpp-docs/issues/2281
Will strerror_s be available in Linux and Android if I select C11 or greater during program build?
Yes.
Always search cppreference.com for C and C++ library reference information. It clearly indicates the answer with the "since C11" in the header.
My code is running on win7 32bit, but when I use EnumProcessModules, it returned false and getlasterror() return error code 299, which declare that the program is 32bit and this statement can not be running on 64bit system.
I wonder why this happens, and why the system thinks that I am running on a 64bit OS?
The code I use:
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
if (hProcess)
{
HMODULE hMod = NULL;
DWORD cbNeeded = 0;
if (EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded))
{
//do something here...
}
}
dwPid is the id of the process I want to manipulate.
PS.This error just happen on one of my test machine, others are fine. So This problem may be related to that specific machine or system configration?
Though It has been a while since you posted this question.But I thought of giving it a try .
Reason might be because You are using CreateProcessA in your code.. and suddenly calling EnumProcessModules.Thus windows is not able to create ModuleInfo by that time.And it returns error 299(Thinking its a 64 bit system.. as it fails to read the memory).
Actually I was stuck at this too and figured it out..after looking at your post.
Thanks
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx
CreatProcess Remarks.. It ask to call WaitforInput Idle before proceeding.;-)
The calling thread can use the WaitForInputIdle function to wait until the new process has finished its initialization and is waiting for user input with no input pending. This can be useful for synchronization between parent and child processes, because CreateProcess returns without waiting for the new process to finish its initialization. For example, the creating process would use WaitForInputIdle before trying to find a window associated with the new process.
I am helping a friend to finish a final year project in which he has this circuit that we want to switch on and off using a C++ program.
I initially thought it would be easy, but I have failed to implement this program.
The main problem is that
Windows XP and above don't allow direct access to hardware so some websites are suggesting that I need to write a driver or find a driver.
I have also looked at some projects online but they seem to work for Windows XP but fail to work for Windows 7.
Also, most projects were written in VB or C# which I am not familiar with.
Question:
Is there a suitable driver that works for Windows XP and Windows 7, and if yes how can I use it in my code? (code snippets would be appreciated)
Is there a cross platform way of dealing communicating with parallel ports?
Have a look at codeproject: here, here and here. You'll find treasures.
The 1st link works for Windows 7 - both 32 bit and 64 bit.
You shouldn't need to write a driver or anything -- you just call CreateFile with a filename like "LPT1" to open up a handle to the parallel port, and then you can use WriteFile to write data to it. For example:
HANDLE parallelPort = CreateFile("LPT1", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if(parallelPort == INVALID_HANDLE_VALUE)
{
// handle error
}
...
// Write the string "foobar" (and its null terminator) to the parallel port.
// Error checking omitted for expository purposes.
const char *data = "foobar";
WriteFile(parallelPort, data, strlen(data)+1, NULL, NULL);
...
CloseHandle(parallelPort);
Disclaimer: This is part of the requirement of the program, so it's not meant for anything bad. Feel free to point out any misuse if you spot one. I'm a beginner in C++.
Basically, I'm trying to restart Outlook.exe on Windows using C++.
And this is the code I used to restart Outlook.
#include <TlHelp32.h>
void RestartOutlook() {
PROCESSENTRY32 Pc = { sizeof(PROCESSENTRY32) };
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);
MODULEENTRY32 Mo = {sizeof (MODULEENTRY32) };
if(Process32First(hSnapshot, &Pc)){
do{
if(!_stricmp(Pc.szExeFile, "outlook.exe")) {
DWORD pid = Pc.th32ProcessID;
HANDLE hModuleSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid);
//kill outlook
HANDLE process = OpenProcess(PROCESS_ALL_ACCESS, TRUE, pid);
DWORD fdwExit = 0;
GetExitCodeProcess(process, &fdwExit);
TerminateProcess(process, fdwExit);
char * path;
if (Module32First(hModuleSnapshot, &Mo)) {
path = Mo.szExePath;
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof (si);
CreateProcess(path, NULL, NULL, NULL, false, NORMAL_PRIORITY_CLASS,
NULL, NULL, &si, &pi);
}
}
}while(Process32Next(hSnapshot, &Pc));
}
}
The funny part is, this piece of code works perfectly fine on Windows 7. While on Windows XP (SP3), I get duplicated Outlook. The GetLastError gives me 6: ERROR_INVALID_HANDLE. I am really clueless after hours of research.
Any idea?
Anyway, C++ is not my field. I do webs :)
And the code above is a mixture of the following sources:
1: http://www.istorya.net/forums/programming/107435-how-can-i-kill-a-process-using-c.html
2: http://code.activestate.com/recipes/576362-list-system-process-and-process-information-on-win/
Environment: Windows 7, Windows XP, VS2010, Outlook 2003, Outlook 2007, Outlook 2010
I found the culprit.
The reason lies in this line:
HANDLE process = OpenProcess(PROCESS_ALL_ACCESS, TRUE, pid);
According to http://msdn.microsoft.com/en-us/library/ms684880(v=vs.85).aspx, PROCESS_ALL_ACCESS is too large for Windows XP/NT system, or more details:
The size of the PROCESS_ALL_ACCESS flag increased on Windows Server 2008 and Windows Vista. If an application compiled for Windows Server 2008 and Windows Vista is run on Windows Server 2003 or Windows XP/2000, the PROCESS_ALL_ACCESS flag is too large and the function specifying this flag fails with ERROR_ACCESS_DENIED. To avoid this problem, specify the minimum set of access rights required for the operation.
Definitely I'm compiling this program on 7, while running on XP definitely causing the problem.
So the solution is, change the PROCESS_ALL_ACCESS to PROCESS_TERMINATE, which
HANDLE process = OpenProcess(PROCESS_TERMINATE, TRUE, pid);
Done!
Thanks #DReJ for quick replies :)
I get that you want Outlook to restart but calling TerminateProcess on Outlook seems like a bad idea in the first place. What if it's in the middle of writing a data file?
A better way would be to find all top-level windows that belong to Outlook, send them a WM_CLOSE and then wait for the process to exit. (You may also have to cope with the user having draft messages open which result in "are you sure" prompts, although if you are doing this in the first place then I assume you know the user isn't in the middle of something?)
An even better way would be to use Outlook's automation interface and tell it to shutdown explicitly.
Your problem maybe related to this piece of code
DWORD fdwExit = 0;
GetExitCodeProcess(process, &fdwExit);
TerminateProcess(process, fdwExit);
First, with GetExitCodeProcess you get status STILL_ACTIVE and after that you terminate process with this status which is not proper I think. Remove GetExitCodeProcess from you code and try TerminateProcess(process, 0); instead.
I'm interested in injecting DLLs into SYSTEM owned processes on my Vista machine. I'm going about this using the traditional method of VirtualAllocEx, WriteProcessMemory and CreateRemoteThread. However, because this will be operating on SYSTEM processes, I enable SeDebugPivilege on the injecting process before opening the target process.
int EnableDebugPriv(LPCTSTR name) {
HANDLE hToken;
LUID luid;
TOKEN_PRIVILEGES tkp;
if(!OpenProcessToken(GetCurrentProcess(),
/*TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY*/
TOKEN_ALL_ACCESS,
&hToken))
return 0;
if(!LookupPrivilegeValue(NULL,name,&luid))
return 0;
tkp.PrivilegeCount=1;
tkp.Privileges[0].Luid=luid;
tkp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
if(!AdjustTokenPrivileges(hToken,false,&tkp,sizeof(tkp),NULL,NULL))
{
printf("!AdjustTokenPrivileges - %d\n",GetLastError());
return 0;
}
if(GetLastError()==ERROR_NOT_ALL_ASSIGNED)
{
return 0;
}
CloseHandle(hToken);
return 1;
}
Where the SE_DEBUG_NAME constant is passed as name.
After enabling SeDebugPrivilege, I go through the process of opening the target process, locating LoadLibrary, allocating space, writing the DLL path to memory, and creating the thread (checking all return values along the way):
if(NULL==(p=OpenProcess(PROCESS_ALL_ACCESS,FALSE,(DWORD)pid)))
...
if(NULL==(loadLib=(LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"),
"LoadLibraryA")))
...
if(NULL==(dllBuff=(LPVOID)VirtualAllocEx(p,
NULL,
strlen(dllPath)+1,
MEM_RESERVE|MEM_COMMIT,
PAGE_READWRITE)))
...
if(NULL==WriteProcessMemory(p,
(LPVOID)dllBuff,
dllPath,
strlen(dllPath),
&written))
...
if(!CreateRemoteThread(p,
NULL,
NULL,
(LPTHREAD_START_ROUTINE)loadLib,
(LPVOID)dllBuff,
NULL,
NULL))
...
dllPath is a char* of the DLL's path (obviously), and pid is the PID of the target process. Both of these values are taken in through the command line and validated before being used.
The problem I'm having is that nothing is returning errors until CreateRemoteThread, which is returning an 8 ("Not enough storage"). HOWEVER, WriteProcessMemory is NOT writing any bytes to the process. After the call the written variable is always 0. No bytes are being written, but the function is not failing. I'm not sure why this is happening. I looked into other privileges, like the SeRestorePrivilege which promises write access to all processes, but nothing works.
I'm executing this program with Administrator rights.
Note: this WriteProcessMemory and CreateRemoteThread problem only happen when I run this program against higher privileged users (SYSTEM, LOCAL SERVICE, etc...). It works perfectly against a program owned by me (same privileges).
Edit: Here's a link to the whole source. http://pastebin.com/m77110d8e There's not much else there besides basic error checking, but maybe it will help?
This has to do with session isolation in Vista or higher versions of Windows. Check out the source or disassembly for password dumping tools like Cain and Abel that purport Vista functionality. Essentially the process is the same but you'll be calling a different function for CreateRemoteThread (sorry, I don't think the function is exported, you just have to find it, so disassembly of working software is probably the best bet).
You could try using RtlCreateUserThread, instead of CreateRemoteThread. This routine doesn't care what session the target process lives in. Just remember to have the thread call RtlExitUserThread before it ends. These threads don't clean up after themselves, like the CreateThread/CreateRemoteThread ones do.
The reactos code can give you a good look at what these routines are doing.