If a thread or process terminates, the OS-internal thread/process object is set to signaled state - the state you can use to wait for with e.g. WaitForSingleObject(). So if hThread is your thread handle, the following would wait until the thread has actually terminated: WaitForSingleObject( hThread, INFINITE ) The point is that you might also use the waiting functions to test if an object (in this case the thread) is in signaled state (in this case has terminated) by just using 0 as the timeout value: if( WaitForSingleObject( hThread, 0 ) == WAIT_TIMEOUT ) { // not terminated yet } -- Daniel Lohmann http://www.losoft.de (Hey, this page is worth looking! You can find some free and handy NT tools there :-D )
Daniel Lohmann
Posts
-
_endthreadex() -
CreateProcess doesn't work while ShellExecute Does!!!!Two potential reasons: 1) the
lpCommandLine
parameter ofCreateProcessW()
is the white-space delimited list of arguments passed asargv
to the new process. If ACDSee expects to find the path to its own executable inargv[0]
the above would fail, as your path contains whitespaces. Basically the result of the above would be: argv[0]="C:\Program", argv[1]="Files\ACD", argv[2]="Systems\ACDSee\6.0}ACDSee6.exe" You should quote the string, e.g. pass it as:L"\"C:\\Program Files\\ACD Systems\\ACDSee\\6.0\\ACDSee6.exe\""
2) The UNICODE-Version ofCreateProcess()
may fail on NT/2k/XP if the parameter passed aslpCommandLine
points to a constant string. This is explicitly mentioned in MSDN. Note that the type isLPWSTR
, notLPCWSTR
. Maybe you should copy your string to a modifiable buffer and pass this buffer toCreateProcessW()
: I usually pass NULL for thelpApplication
parameter and only uselpCommandLine
. Of course, you have to make sure that a path containing white-spaces is quoted in this case (as described above). ShellExecute() is intended to be more "user friendly", that is it applies some heuristics to resolve pathes containing white spaces and does other "magic stuff". Hope that helps -- Daniel Lohmann http://www.losoft.de (Hey, this page is worth looking! You can find some free and handy NT tools there :-D ) -
Thread Control and WaitCommEvent()Aehm, more or less. Overlapped IO is a feature of the NT Executive (Kernel) and the Win32 API and not related to any classes. The IO Manager (a component of the Executive) executes IO request always asynchronously - if you don't use overlapped IO the calling thread is just blocked until the IO is completed. (In other words: Inside the kernel non-overlapped IO is simulated by using overlapped IO) However, I am sure you that much interested in the technical details, but want to know how to use it :-D Overlapped IO is not difficult in general, but a lot of details have to be taken into account. If the information provided by MSDN is not enough, I'd recommend to buy a good book about Windows NT system programming, like Win32 System Programming by Johnson M. Hart. (Note: I haven't read it, but people told me that it's a quite good book). Hope that helps! -- Daniel Lohmann http://www.losoft.de (Hey, this page is worth looking! You can find some free and handy NT tools there :-D )
-
WNetAddConnection2What is about just "using" the connection every, lets say, 10 minutes. (List the directory, access some file or, if it is not a connection to an UNC share, call an API that routes over IPC$ like remote registry access or the SCM API.) Then the system should not detect it as beeing idle :-D -- Daniel Lohmann http://www.losoft.de (Hey, this page is worth looking! You can find some free and handy NT tools there :-D )
-
Thread Control and WaitCommEvent()Like almost any file IO in Win32 WaitCommEvent() supports overlapped IO. This means that your call to executed asynchronously by the IOManager in background. You receive the results via the OVERLAPPED structure passed as last parameter. Overlapped IO is discussed in detail in MSDN. -- Daniel Lohmann http://www.losoft.de (Hey, this page is worth looking! You can find some free and handy NT tools there :-D )
-
named objects from serviceian mariano wrote: If you're not using Terminal Services, as the above link states, then "Global\" would be ignored. ...unless you are running on NT4. There the global prefix would cause an error! -- Daniel Lohmann http://www.losoft.de (Hey, this page is worth looking! You can find some free and handy NT tools there :-D )
-
Message cross threadsBTW: Your E-Mail address seems to be incorrect. I got an "Undeliverable Mail" message for steven_wng@sina.com on my previous post. Hope you check the forum as well :-) -- Daniel Lohmann http://www.losoft.de (Hey, this page is worth looking! You can find some free and handy NT tools there :-D )
-
Message cross threadsWhat? :wtf::omg: Sorry, includeh10, but you seem to completly misunderstood the concept of threads. You can pass pointers between threads as long as you make sure they reside in the same process. All threads inside a process share the same address space, therefore any address reference is valid and accessable by every thread. Actually this easiness of inter-thread communication is the main reason we use threads instead of processes. COM puts a lot of "magic stuff" (like apartments, free threaded marshaller, ...) around this, because it has to guarantee that it even works if both thread reside in different processes or even on different machines. -- Daniel Lohmann http://www.losoft.de (Hey, this page is worth looking! You can find some free and handy NT tools there :-D )
-
Completion Port and Multithreads :: MFCAfxBeginThread() is just a small wrapper around _beginthreadex and does some extra MFC structure initialisations on thread creation and some cleanup on thread termination. If you are using the DLL version of MFC you don't have to care that much about it, because the same job is done in MFC42.dll's DllMain(). From the performance point of view both should be pretty the same. I usually prefer _beginthreadex() - just because you may decide one day to throw MFC away from your server app (which is not that unlikely, believe me :) ) -- Daniel Lohmann http://www.losoft.de (Hey, this page is worth looking! You can find some free and handy NT tools there :-D )
-
Message cross threadsYou are developing on Win64? Wow :cool: Your problem sounds a bit strange. It should work as you described, I can't find anything conspicuous in your code. I would suppose a subtle side effect: - Are you sure the value of WM_HYDRO_RXD_ARRIVAL is unique and you are not accidently catching the wrong message? - Are you sure _W64 is always defined and really all data types are used as 64 bit types? - Did you monitor any other side effects that look like memory corruption occuring somewhere in your app? - Does the same problem appear in a small test app? (Hm the above looks a bit like the generic "are you sure the power cable is plugged in" hotline answer :-O ) Good luck! -- Daniel Lohmann http://www.losoft.de (Hey, this page is worth looking! You can find some free and handy NT tools there :-D )
-
LogonUser?- What is the result of GetLastError()? 2) What OS version, SP you are using? The most common mistake using LogonUser() is that it needs SE_TCB_PRIVILEGE on pre-XP systems. This privilege is (and should be!) granted only to the SYSTEM account, which means that actually only service processes are able to perform a LogonUser() -- Daniel Lohmann http://www.losoft.de (Hey, this page is worth looking! You can find some free and handy NT tools there :-D )
-
My network refuses toDid you build the second PC by cloning the first one or build them up from the very same image? This is a common reason for effects like the one you described. -- Daniel Lohmann http://www.losoft.de (Hey, this page is worth looking! You can find some free and handy NT tools there :-D )
-
IPC: named shared memoryThe usual (and most easy) way to pass the inherited handles to a child process is via the command line or environment variables. -- Daniel Lohmann http://www.losoft.de (Hey, this page is worth looking! You can find some free and handy NT tools there :-D )
-
Shall we do other peoples homework?Michael P Butler wrote: If they don't get the basic research and learning skills down then they'll end up having a very hard life (Either that or they'll become managers ) Ah, recruiting them for management! Indeed a solution! :laugh: However, I am still afraid the become developer and you or me is forced to work with them :~ -- Daniel Lohmann http://www.losoft.de (Hey, this page is worth looking! You can find some free and handy NT tools there :-D )
-
Shall we do other peoples homework?Christopher Duncan wrote: the only thing I really care about is whether or not the person asking the question is truly trying to get it, and willing to do their own work to get there after a little help. Christian Graus wrote: I'm pretty sure I helped someone with his homework today, but he'd clearly tried to do it himself, asked politely and generally was not demanding. Under those circumstances I am happy to help people. It's folks who post 'I need the Towers of Hanoi in C by tomorrow' ( true story ) who make me mad, but if someone is trying to learn, the fact that they are at school will not stop me from helping them. Me wrote: I have no problems helping them if they really tried to do it on their own first - quite the reverse! Seems that we all agree in one point :): If they are willing to put own effort into it, they are welcome. If not, ... -- Daniel Lohmann http://www.losoft.de (Hey, this page is worth looking! You can find some free and handy NT tools there :-D )
-
Shall we do other peoples homework?Hi everybody, In the last months, answering programming questions in the forums, I got the feeling that we are more and more "misused" by pupils and undergraduate students to do their homework for them. There are a lot of questions which really do smell like typical homework questions: Could anyone tell me why disabling interupts to achieve mutual exclusion is not acceptable on a multiprocessor sytem? How to change number data from base 256 to base 16? ... Of course it is the job of the teachers and not ours to ensure that they do their homework on their own ;P. And I have no problems helping them if they really tried to do it on their own first - quite the reverse! However, sometimes it looks like that the questioner even did not tried to understand the question, but just posted it to the forum. Shall we really do answer this kind of questions? Do we need a kind of "CodeProject agreement" about handling such cases? -- Daniel Lohmann http://www.losoft.de (Hey, this page is worth looking! You can find some free and handy NT tools there :-D )
-
IPC: named shared memorynorm wrote: can i programatically generate a GUID to use as the "name" of "named shared memory" created by call to CreateFileMapping(..) ??
CoCreateGuid()
will do it :-) norm wrote: and if I want to create "no-name" file mapping, how can I communicate the handle to the file mapping object to a separate process? WM_COPYDATE?? Yes, this means you have to use some other IPC channel to send the HANDLE to the target process. WM_COPYDATA is one idea, if the first process creates the second one, you could also use handle inheritance. However, a named object is usually the most convinient solution. BTW: I recommend to use not only a GUID for the name, but also a "human readable" part (somthing likeMy_app_shared_data_63dcc4b9-b122-4337-b897-88f6a7f49f3f
). This would make it much easier for you and others to find your section in tools like Process Explorer and other debugging tools. -- Daniel Lohmann http://www.losoft.de (Hey, this page is worth looking! You can find some free and handy NT tools there :-D ) -
Replacing GINAAre you sure you setup proper security descriptors for the WinSta0 and WinSta0/Default windowstation/desktop objects? Seems that the user account the shell process is running under has not the proper access rights to create menus. -- Daniel Lohmann http://www.losoft.de (Hey, this page is worth looking! You can find some free and handy NT tools there :-D )
-
Shared MemoryPaul wrotes: I believe that because the FileMapping object is a Kernel object, that the file mapping will continue to exist until all handles to it are released. Paul is absolutely right here. A (named) file mapping is a kernel object and will exists, until the last handle to it has been closed. So in your scenarion the mapping will still be present and valid, because at every time there is at least one valid handle to it. BTW: Using native NT Api it is even possible to make a kernel object "persistent", meaning that it would continue to exist after the last handle to it has been closed (persistent means until next reboot). Of course this makes sense only for named kernel objects. Even if sometimes fairly useful, this is undocumented and therefore "not recommended" :-( -- Daniel Lohmann http://www.losoft.de (Hey, this page is worth looking! You can find some free and handy NT tools there :-D )
-
Callback continuedThunking/converting thiscall to callback without using fancy assembler tricks, but adapter objects and C++ standard language features as described in my article Use member functions for C-style callbacks and threads - a general solution. The article focusses on dealing with the typical Win32 API callbacks, however, the underlaying technique is generic and portable. -- Daniel Lohmann http://www.losoft.de (Hey, this page is worth looking! You can find some free and handy NT tools there :-D )