|
ForNow wrote: I would have to create a message pump via GetMessage,TranslateMessage,DispatchMessage
Hi,
Calling the PostMessage function exported from user32.dll results in a NtUserPostMessage system call. This alone should be enough to promote the thread to a gui thread via KiConvertToGuiThread . Note that things are changing as security features are being added to the Microsoft Windows platform. You would need to make sure that PROCESS_CREATION_MITIGATION_POLICY_WIN32K_SYSTEM_CALL_DISABLE_ALWAYS_ON is not defined. This security feature disables win32k system calls for a process/thread.
ForNow wrote: Second What Makes SendMessage with WM_COPYDATA message so special that it is Sanctioned
By MicroSoft
You are essentially asking:
1.) Why does User Interface Privilege Isolation exist?
2.) Why is the old message model (for inter-process communication) being deprecated ?
Basically the answer is:
For a future with better secure computing platform and secure internet connectivity.
Recent hacking attacks described in the media (i.e. democratic national convention) could have potentially been mitigated by defining PROCESS_CREATION_MITIGATION_POLICY_WIN32K_SYSTEM_CALL_DISABLE_ALWAYS_ON on browser/e-mail rendering threads. Essentially a 'system call' attack surface reduction.
Always use a modern up-to-date browser. I recommend Microsoft Edge or Google Chrome.
Chromium Win32k system call lockdown[^]
Security enhancements for Microsoft Edge[^]
Hopefully one day software companies will be required to adhere to an international standard for secure computing. We are still in the wild-west early stages of computing.
Best Wishes,
-David Delaune
|
|
|
|
|
Lets first discuss the general Windows cases. Basic rule never use SendMessage between any windows that you don't directly know the message arrangements use PostMessage instead. The other trap with SendMessage is it is easy to go circular (happens a lot when playing around with scrollbar code ). Make sure the send message handling doesn't send a messsage back to the caller which then sends off another message and around and around it goes.
I also have a scary feeling you have a different thread on the console app given the title Interprocess. If that is true you can not blindly use SendMessage, it crosses a thread boundary and it will deadlock .... Guaranteed if done raw. It is sort of covered in the Microsoft discussion of SendMessage when they talk about the data marshalling and playing around with SendMessageTimeout. The easier solution is just don't use it, PostMessage is there and has no issues. If you need a response back you post back another message so you setup a ping/pong message system using PostMessage, saves a lot of effort and heartache.
In the directory watcher code I did for you that is why I used PostMessage in the thread not SendMessage. Use SendMessage there and it will Deadlock randomly.
PostMessage(watchData->AppWindow, watchData->MsgId, watchData->CmdId, (LPARAM)msgToApp);
Randor in his post is correct if you want to tow the "Microsoft line", so I guess look at is what you are coding a critical system. Historically most have always used WM_USER and I have never seen a clash because there is really only you, Windows and your framework that post messages around inside your application and you can see it in testing and debugging on your machine. This isn't a bug that would suddenly appear in the field or such, it was always more a problem if you had two or more programmers and they both selected the same message number you got some funny things happen. Anyhow if you are going to stick to messages perhaps move up to WM_APP messages (It came in with Windows 95) because that range is designed to do exactly what you are doing and will be one more bit of safety. None of these message ranges go inside/outside your applications so it's only stuff within your application you have to worry about.
AFAIK windows itself puts no messages into the WM_USER range these days because of the data marshal requirements and I believe it has been like that since Win95. Even the classic old ones like LB_ADDSTRING got moved into the standard windows range. LB_ADDSTRING used to be WM_USER + 1 which is why us old timers used to go for WM_USER+100, it was our goto number
For what it's worth having two window elements with the same ID happens a lot more and is just as catastrophic. There is no way to stop it happening except by controlling the allocation of ID numbers to elements. An interesting programming office prank was to get hold of a resource editor and move the ID numbers around on exe which had the resources bound and watch the fun that followed (Borlands whitewater resource kit was so good at it). Some even had the menus in the resource and you could change the menu ID numbers.
In vino veritas
modified 2-Nov-16 10:36am.
|
|
|
|
|
thanks But PostMessage Windows -> console wont work because the console app doesn't have a
message queue. I know the GetMessage,TranslateMessage,DispatchMessage creates one.
Or Rather the GetMessage
I have a question about the Message Structure
Since the console app doesn't a windows the Hwnd is NULL
What about the last parameter of the message structure the Point parameter what would
its value be in the console application
|
|
|
|
|
Okay lets first deal with your misconceptions
Windows console windows do have a window handle it just has a special function to get it because it isn't present by default because you start with main not winmain and main has no position for it on it's parameters which are arguments.
GetConsoleWindow function (Windows)[^]
You can also directly pull the message handler if you want to just provide your own that looks like this
WNDPROC ConsoleWindow = NULL;
static LRESULT CALLBACK MyWndProc(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
if (ConsoleWindow)
return CallWindowProc(ConsoleWindow, Wnd, Msg, wParam, lParam);
return(0);
}
HWND hWnd = GetConsoleWindow();
ConsoleWindow = (WNDPROC)SetWindowLong(hWnd, GWL_WNDPROC, (LONG)MyWndProc);
However since Win95 we tend not to do that anymore because there is a much easier way with a special class called Message-Only Windows. There are even a couple of articles on using them in the code project archives but it's just like any normal window just it has no visible parts.
The 3rd alternative is you make a normal windows program and create a console window from the launch using AllocConsole.
AllocConsole function (Windows)[^]
Lots of science and maths guys do this so they can dump data out onto the console window while running there graphics.
You do not have to have a graphics window however you can simply use the stdin and stdout ... here is the simplest sample. Compile it as a standard windows GUI project.
So again in this sample you have a standard message queue available and a console window.
#include <windows.h>
#include <tchar.h>
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
DWORD charsRead = 0;
TCHAR keyBuffer[100];
AllocConsole();
HANDLE myConsoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
DWORD cCharsWritten;
TCHAR* str = TEXT("Hello I am the console\r\n");
WriteConsole(myConsoleHandle, str, _tcslen(str), &cCharsWritten, NULL);
HANDLE myConsoleHandleInput = GetStdHandle(STD_INPUT_HANDLE);
ReadConsole(myConsoleHandleInput, keyBuffer, _countof(keyBuffer), &charsRead, NULL);
str = TEXT("Okay lets mix it up with messages and console .. any key to exit\r\n");
WriteConsole(myConsoleHandle, str, _tcslen(str), &cCharsWritten, NULL);
DWORD events = 0;
INPUT_RECORD input_record = { 0 };
MSG Msg = { 0 };
do {
Msg.message = 0;
input_record.EventType = 0;
BOOL peek = PeekConsoleInput(myConsoleHandleInput, &input_record, 1, &events);
if (peek == FALSE) {
if (PeekMessage(&Msg, 0, 0, 0, PM_REMOVE)) {
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
} else {
ReadConsoleInput(myConsoleHandleInput, &input_record, 1, &events);
}
} while ((Msg.message != WM_QUIT) && (input_record.EventType != KEY_EVENT));
}
In typical windows style there are multiple ways of doing the same thing
In vino veritas
modified 3-Nov-16 0:09am.
|
|
|
|
|
I have a few questions on the following cryptography functions.
1)
BOOL WINAPI CryptGenKey(
_In_ HCRYPTPROV hProv,
_In_ ALG_ID Algid,
_In_ DWORD dwFlags,
_Out_ HCRYPTKEY *phKey
); This is supposed to generate a private/public key pair, which is maintained between sessions.
Q: What is the effect of repetitive calls to this function? For example, I decide to change the key length, and generate a call with a different dwFlags value. What happens to the old key pair? Does it get overwritten? Or does each new call generate a new key pair?
2)
BOOL WINAPI CryptGetUserKey(
_In_ HCRYPTPROV hProv,
_In_ DWORD dwKeySpec,
_Out_ HCRYPTKEY *phUserKey
);
MSDN: “The CryptGetUserKey function retrieves a handle of one of a user's two public/private key pairs.”
Q: which one?
MSDN: “dwKeySpec [in]
Identifies the private key to use from the key container.”
In this example, MSDN says
if(CryptGetUserKey(
hProv,
AT_SIGNATURE,
&hKey))
{ Q: So how does one retrieve the public key, and how does one get the private key?
3)
BOOL WINAPI CryptDestroyKey(
_In_ HCRYPTKEY hKey
); MSDN: “However, the underlying public/private key pair is not destroyed by this function. Only the handle is destroyed.”
Q: How can the public/private key pair be destroyed?
Thank you!
|
|
|
|
|
Hi,
SMD111 wrote: Q: What is the effect of repetitive calls to this function? For example, I decide to change the key length, and generate a call with a different dwFlags value. What happens to the old key pair? Does it get overwritten? Or does each new call generate a new key pair?
Each call generates a new key pair. Each key remains valid until you call the CryptDestroyKey function or until you reboot. If you wanted to save the key... you could export it or save it into the certificate store.
SMD111 wrote: MSDN: “The CryptGetUserKey function retrieves a handle of one of a user's two public/private key pairs.”
Q: which one?
There is no default for zero-value. You would probably get a ERROR_INVALID_PARAMETER error if you pass zero. You would need to specify either AT_KEYEXCHANGE or AT_SIGNATURE. Currently defined as integers 1 and 2.
SMD111 wrote: Q: So how does one retrieve the public key, and how does one get the private key?
See the previous response. You would need to pass AT_KEYEXCHANGE or AT_SIGNATURE. Note that AT_SIGNATURE keys can be used to sign and AT_KEYEXCHANGE keys can
be use both to sign and decrypt.
SMD111 wrote: Q: How can the public/private key pair be destroyed?
The question is either unclear or nonsensical. When you call CryptDestroyKey the handle to an internal object is securely deleted.
It is up to you to securely delete your own application memory and destroy any exported keys and/or remove keys from the certificate store or on disk.
One last thing... while working internally on an operating system service I discovered multiple failures... including a race condition within the old Crypt32 Cryptography Functions.
Our team moved to the 'Cryptography Next Generation' and all issues were resolved.
Best Wishes,
-David Delaune
|
|
|
|
|
Hello ! I just started to play around with C lately(and mainly with pointers). For practice, i created this function that is suppose to create a random string:
char *ReturnRandomString(int Range)
{
char StringsToChooseFrom[26] = {'q','w','e','r','t','y','u','i','o','p','a','s','d','f','g','h','j','k','l','z','x','c','v','b','n','m'};
char MyArray[Range + 1];
char *Ptr_str;
int i;
for(i = 0; i < Range; i++)
{
srand(time(NULL));
int RandomInt = rand() & 26;
MyArray[i] = StringsToChooseFrom[RandomInt -1];
}
MyArray[i + 1] = '\0';
Ptr_str = malloc(sizeof(MyArray));
Ptr_str = MyArray;
return(Ptr_str);
}
I am "calling" this function this way:
char *PtrCharArray = ReturnRandomString(5);
printf("\nString Array returned: %s", PtrCharArray);
The output... is nothing. I don't neither an output on the console... either an error.
It's sure that i am missing something, but i don't know what. Thanks in advance !!!
P.S No hate.
|
|
|
|
|
char MyArray[Range + 1];
Ptr_str = malloc(sizeof(MyArray)); Ptr_str = MyArray; return(Ptr_str);
That won't work:
1. You cannot allocate an array on the stack using a variable value.
2. sizeof is compile time so it cannot calculate the actual size of the array. You need to use strlen .
3. You cannot use an assignment to copy data. You need to use a copy function: memcpy or strcpy MyArray to Ptr_str .
|
|
|
|
|
1. You cannot allocate an array on the stack using a variable value.
C99 and C11 both permit this. Additionally, both gcc and clang will accept this when compiling in C89 mode, too.
If you're using a POSIX system, then rather than doing malloc() and strcpy() then perhaps use strdup() instead. MSVC has _strdup(), which does the same thing.
|
|
|
|
|
Thank you. Actually I did think that was the case, but when I tried to compile it the compiler objected, so I assumed I just mis-remembered.
|
|
|
|
|
There are some more errors besides those mentioned by Richard.
Here you would normally use the % operator so that the value is in the range 0 to 25:
int RandomInt = rand() & 26;
Anding with 26 (0x1A) will clear masked out bits so that the possible values are only 0x00, 0x02, 0x08, 0x0A, 0x12, 0x18, and 0x1A.
Here you should remove the subtraction of one because that accesses the array out of bounds when RandomInt is zero:
MyArray[i] = StringsToChooseFrom[RandomInt -1];
See the rand() description:
Quote: The rand() function returns a pseudo-random integer in the range 0 to RAND_MAX inclusive.
|
|
|
|
|
What Jochem said .. RTM and look at the examples you need to use the MODULO trick
Can you also please put this line up before the i loop
srand(time(NULL));
That just sets the random seed to the current time tick which updates every second again RTM on C standard time function.
I assure you that loop will complete far faster than 1 second on any decent computer so you are wasting time setting the same seed i times.
You might as well just do it once before the loop
In vino veritas
modified 27-Oct-16 9:49am.
|
|
|
|
|
In addition to the other comments and suggestions:
_TCHAR *ReturnRandomString( int Range )
{
_TCHAR *Ptr_str = (_TCHAR *) malloc(Range + 1);
int i;
for (i = 0; i < Range; i++)
{
int RandomInt = rand() % 26;
Ptr_str[i] = (_TCHAR) (RandomInt + 97);
}
Ptr_str[i] = _T('\0');
return Ptr_str;
}
...
srand(time(NULL));
_TCHAR *PtrCharArray = ReturnRandomString(5);
_tprintf(_T("String Array returned: %s\n"), PtrCharArray);
free(PtrCharArray);
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"You can easily judge the character of a man by how he treats those who can do nothing for him." - James D. Miles
|
|
|
|
|
_TCHAR *Ptr_str = (_TCHAR *) malloc(Range + 1);
This line only allocates the correct amount of memory if sizeof(_TCHAR) == 1. The correct code would multiply the length by sizeof(_TCHAR).
Ptr_str[i] = (_TCHAR) (RandomInt + 97);
This line only works on character sets that encode the alphabet consecutively. This is true for ASCII and Unicode, but not for all varieties of EBCDIC, for example.
A portable solution would be as follows:
static _TCHAR const chars[] = _T("abcdefghijklmnopqrstuvwxyz");
TCHAR *Ptr_str = (_TCHAR *) malloc((sizeof(_TCHAR)*(Range + 1));
...
Ptr_str[i] = chars[RandomInt];
Where _TCHAR and _T(x) have appropriate definitions for the environment.
If you have an important point to make, don't try to be subtle or clever. Use a pile driver. Hit the point once. Then come back and hit it again. Then hit it a third time - a tremendous whack.
--Winston Churchill
|
|
|
|
|
May this will help...
char *ReturnRandomString(int Range)
{
char StringsToChooseFrom[26] = {'q','w','e','r','t','y','u','i','o','p','a','s','d','f','g','h','j','k','l','z','x','c','v','b','n','m'};
char MyArray[100] = {}; char *Ptr_str;
int i;
for(i = 0; i < Range; i++)
{
int RandomInt = rand() % 26;
MyArray[i] = StringsToChooseFrom[RandomInt];
}
MyArray[i + 1] = '\0';
Ptr_str = (char*)malloc(sizeof(MyArray)); strcpy(Ptr_str, MyArray ); return(Ptr_str);
}
int _tmain(int argc, _TCHAR* argv[])
{
srand(time(NULL)); for( int i = 0; i < 10; i++ )
{
char *PtrCharArray = ReturnRandomString(i);
printf("\nString Array returned: %s\n", PtrCharArray);
}
return 0;
}
|
|
|
|
|
Only as long as Range < 100.
Which also brings up the question of what happens if Range < 0. It might be better to use size_t for Range and your loop variable i. You should probably check the return value of malloc() too, just to be safe.
Oh. And you're leaking the results of ReturnRandomString(). There should probably be a free() when you are done with it.
|
|
|
|
|
|
Krishnakumartg wrote:
MyArray[i + 1] = '\0'; Why add 1 ? When the loop ends, i is already 1 past the desired length.
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"You can easily judge the character of a man by how he treats those who can do nothing for him." - James D. Miles
|
|
|
|
|
I have a .Net/WPF application which calls methods on a DLL. One of these methods - Load() - calls CoCreateInstance to load a COM server provided by a third party. If I do all this in the Load() thread, it works fine i.e. Load() calls CoCreateInstance directly.
However if Load() creates a worker thread, and then waits for completion, the CoCreateInstance call hangs. If I remove the wait, so that Load() returns before the worker thread completes, it works. The CoCreateInstance call returns AFTER the Load() function returns.
Anyone know what is happening? It is as if it is serialising the COM access for some reason ...
|
|
|
|
|
|
Thanks for the comments. I have tested using a simple Win32 C++ console application to drive our DLL, and it works fine when using the worker thread to invoke COM commands to the third party component. So clearly this is something to do with the .Net application.
Okay, I have solved it.
A COM STA uses Windows messages to serialise access to the COM object which might not be thread safe. So when I created a worker thread, the main thread then hung waiting for the worker thread to finish, but it never did, as the main thread hanging blocked the message pump! Instead of the main thread waiting, I now make it periodically run a message pump to ensure that messages are process. That has solved the problem. Yikes. I hate COM!
Thank you for your helpful post.
Added later: I have also looked into removing the worker thread and marshalling the COM interfaces across threads and this works. It has the advantage that I do not have to mess around with a message pump, which is akin to spinning the tyres.
modified 10-Nov-16 10:36am.
|
|
|
|
|
You could try calling CoInitialize[^] in the worker thread before the call to CoCreateInstance .
«_Superman_»
I love work. It gives me something to do between weekends.
Microsoft MVP (Visual C++) (October 2009 - September 2013) Polymorphism in C
|
|
|
|
|
Thanks for the comment. Yes I call CoInitialise, that is not the issue. I wish it was. 
modified 9-Nov-16 3:51am.
|
|
|
|
|
Hi, i have to ask a question about some codelines, where i have a mistake, because the array of int always returns 1 for every instance and i spent a lot of hours and still cannot find the fail i have maid.
I simply post the necessary codelines in hope that someone can put away the wood infront of my head.
Inside a modal dialogue, these are the calls
for (int y=0;y<5;y++)
{
Schadensnummer[y]=KlendautKlendaut_Gegner[0].Basistrefferermittlung();
}
The class "KlendautKlendaut_Gegner0" - function Basistrefferermittlung:
int CBasis::Basistrefferermittlung()
{
int Zufallstreffer;
Zufallstreffer=rand()%99+1;
int Trefferchance;
Trefferchance=rand()%99+1;
static int Einschlagsnummer;
if (Trefferchance>80)
{
if (Zufallstreffer>95)
{
if (m_Bodyguard>1)
{
Einschlagsnummer=20;
m_Bodyguard=m_Bodyguard-1;
return (Einschlagsnummer);
}
else if (m_Bodyguard<1&&m_Palast>1)
{
Einschlagsnummer=21;
m_Palast=m_Palast-1;
return (Einschlagsnummer);
}
}
else if (Zufallstreffer>90&&Zufallstreffer<95)
{
if (m_Fabrik>1)
{
Einschlagsnummer=16;
m_Fabrik=m_Fabrik-1;
return (Einschlagsnummer);
}
}
else if (Zufallstreffer>85&&Zufallstreffer<90)
{
if (m_Scanner>1)
{
Einschlagsnummer=17;
m_Scanner=m_Scanner-1;
return (Einschlagsnummer);
}
}
else if (Zufallstreffer>80&&Zufallstreffer<85)
{
if (m_Kraftwerk>1)
{
Einschlagsnummer=18;
m_Kraftwerk=m_Kraftwerk-1;
return (Einschlagsnummer);
}
}
else if (Zufallstreffer>75&&Zufallstreffer<80)
{
if (m_Zentrale>1)
{
Einschlagsnummer=19;
m_Zentrale=m_Zentrale-1;
return (Einschlagsnummer);
}
}
}
if (m_Schutzwall>1)
{
Einschlagsnummer=1;
m_Schutzwall=m_Schutzwall-1;
return (Einschlagsnummer);
}
else if (m_Gefechtsstand>1)
{
Einschlagsnummer=2;
m_Gefechtsstand=m_Gefechtsstand-1;
return (Einschlagsnummer);
}
else if (m_Geschuetzturm>1)
{
Einschlagsnummer=3;
m_Geschuetzturm=m_Geschuetzturm-1;
return (Einschlagsnummer);
}
else if (m_Drohnen>1)
{
Einschlagsnummer=4;
m_Drohnen=m_Drohnen-1;
return (Einschlagsnummer);
}
else if (m_Marines>1)
{
Einschlagsnummer=5;
m_Marines=m_Marines-1;
return (Einschlagsnummer);
}
else if (m_Werkspolizei>1)
{
Einschlagsnummer=6;
m_Werkspolizei=m_Werkspolizei-1;
return (Einschlagsnummer);
}
else if (m_Unterkunft>1)
{
Einschlagsnummer=7;
m_Unterkunft=m_Unterkunft-1;
return (Einschlagsnummer);
}
else if (m_ErhZentrum>1)
{
Einschlagsnummer=8;
m_ErhZentrum=m_ErhZentrum-1;
return (Einschlagsnummer);
}
else if (m_EinkZentrum>1)
{
Einschlagsnummer=9;
m_EinkZentrum=m_EinkZentrum-1;
return (Einschlagsnummer);
}
else if (m_Bunker>1)
{
Einschlagsnummer=10;
m_Bunker=m_Bunker-1;
return (Einschlagsnummer);
}
else if (m_Lager>1)
{
Einschlagsnummer=11;
m_Lager=m_Lager-1;
m_Lagerpunkte=m_Lagerpunkte-150;
return (Einschlagsnummer);
}
else if (m_Forschung>1)
{
Einschlagsnummer=12;
m_Forschung=m_Forschung-1;
return (Einschlagsnummer);
}
else if (m_MedZentrum>1)
{
Einschlagsnummer=13;
m_MedZentrum=m_MedZentrum-1;
return (Einschlagsnummer);
}
else if (m_Schild>1)
{
Einschlagsnummer=14;
m_Schild=m_Schild-1;
return (Einschlagsnummer);
}
else if (m_Firewall>1)
{
Einschlagsnummer=15;
m_Firewall=m_Firewall-1;
return (Einschlagsnummer);
}
else if (m_Fabrik>1)
{
Einschlagsnummer=16;
m_Fabrik=m_Fabrik-1;
return (Einschlagsnummer);
}
else if (m_Scanner>1)
{
Einschlagsnummer=17;
m_Scanner=m_Scanner-1;
return (Einschlagsnummer);
}
else if (m_Kraftwerk>1)
{
Einschlagsnummer=18;
m_Kraftwerk=m_Kraftwerk-1;
return (Einschlagsnummer);
}
else if (m_Zentrale>1)
{
Einschlagsnummer=19;
m_Zentrale=m_Zentrale-1;
return (Einschlagsnummer);
}
else if (m_Bodyguard>1)
{
Einschlagsnummer=20;
m_Bodyguard=m_Bodyguard-1;
return (Einschlagsnummer);
}
else if (m_Palast>1)
{
Einschlagsnummer=21;
m_Palast=m_Palast-1;
return (Einschlagsnummer);
};
}
The array of Schadensnummer[5] always return 1 (Einschlagsnummer==1) out of Basistrefferermittlung. But the class KlendautKlendaut_Gegner[0].m_Schutzwall ist declared only 1 at this point and it is reduced in Basistrefferermittlung. So in the second call of this function it must be 0 and so the Schadensnummer[1] has to be 2. But it stays 1 for every instance of Schadensnummer[].
Does someone has a suggestion?
|
|
|
|
|
Use a debugger and step through the function. If a variable's value is not what you are expecting it is a lot easier to find out why by watching when it changes than by peering through the code looking for clues.
|
|
|
|
|