From: GrepAll on
We know that each time Windows 2003 Server been shutdown, there will
be a dialog which requests the user to input/select the reason. This
reason will be recorded in the registry. If the shutdown occurs
without this step (shutdown reason dialog), a similar dialog will be
pop in the next time Windows 2003 Server startup, for the user to
record the last shutdown reason.

Here comes the problem: Can I simulate the action which the dialog
does manually? That is, is there a way after I execute a code block
(or call an API), then Windows will treat a power failure as normal
shutdown?

I noticed there is a function exported by USER32.DLL calls
RecordShutdownReason, which is called by MSGINA.DLL. I think it may
meet my requirement, but I cannot get any more information of this
function. I also try to call the function in my test application.
Pressed the power button after called this function, it doesn't work.
Windows still asked me to input the unexpected shutdown reason after
reboot.

Any advice is welcome, thanks!

From: Rymfax on
NEVERMIND! I figured it out! :) For those of you that might want the
answer, I just had to use LoadLibrary and GetProcAddress to access the
function. Here is the code I used:

BOOL B;
HINSTANCE Krnl32=LoadLibrary(L"kernel32.dll");
if(Krnl32 !=NULL) {
int ret=0;

//IsDebuggerPresent...No exception
BOOL (WINAPI *IsDebuggerPresent)() = NULL;
IsDebuggerPresent = (BOOL (WINAPI *)())GetProcAddress(Krnl32,
"IsDebuggerPresent");
if (IsDebuggerPresent != NULL) {
ret = (*IsDebuggerPresent)();

ret=0;
PDWORD pdwReturnedProductType=0;


BOOL (WINAPI *GetProductInfo)
(DWORD,DWORD,DWORD,DWORD,PDWORD)=NULL;
GetProductInfo=(BOOL (WINAPI *)(DWORD,DWORD,DWORD,DWORD,PDWORD))
GetProcAddress(Krnl32,
"GetProductInfo");
B=(*GetProductInfo)(osvi.dwMajorVersion,osvi.dwMinorVersion,
0,0,&productType);
if(B)
{
osString=getProductTypeString(productType);
}
//else
// MessageBox(0, L"B Was FALSE", L"ERROR", MB_OK);
}
//else
// MessageBox(0, L"IsDebuggerPresent Was NULL", L"ERROR", MB_OK);
FreeLibrary(Krnl32);
}
//else
// MessageBox(0, L"Krnl32 Was NULL", L"ERROR", MB_OK);



From: GrepAll on
I'm not meant to ask how to call a Dll-exported function. But to know
how does RecordShutdownReason works.

Anyway, thanks for your answer.:-)

GrepAll

On 5ÔÂ23ÈÕ, ÉÏÎç2ʱ55·Ö, Rymfax <cwal...(a)bigbangllc..com> wrote:
> NEVERMIND! I figured it out! :) For those of you that might want the
> answer, I just had to use LoadLibrary and GetProcAddress to access the
> function. Here is the code I used:
>
> BOOL B;
> HINSTANCE Krnl32=LoadLibrary(L"kernel32.dll");
> if(Krnl32 !=NULL) {
> int ret=0;
>
> //IsDebuggerPresent...No exception
> BOOL (WINAPI *IsDebuggerPresent)() = NULL;
> IsDebuggerPresent = (BOOL (WINAPI *)())GetProcAddress(Krnl32,
> "IsDebuggerPresent");
> if (IsDebuggerPresent != NULL) {
> ret = (*IsDebuggerPresent)();
>
> ret=0;
> PDWORD pdwReturnedProductType=0;
>
> BOOL (WINAPI *GetProductInfo)
> (DWORD,DWORD,DWORD,DWORD,PDWORD)=NULL;
> GetProductInfo=(BOOL (WINAPI *)(DWORD,DWORD,DWORD,DWORD,PDWORD))
> GetProcAddress(Krnl32,
> "GetProductInfo");
> B=(*GetProductInfo)(osvi.dwMajorVersion,osvi.dwMinorVersion,
> 0,0,&productType);
> if(B)
> {
> osString=getProductTypeString(productType);
> }
> //else
> // MessageBox(0, L"B Was FALSE", L"ERROR", MB_OK);
> }
> //else
> // MessageBox(0, L"IsDebuggerPresent Was NULL", L"ERROR", MB_OK);
> FreeLibrary(Krnl32);
> }
> //else
> // MessageBox(0, L"Krnl32 Was NULL", L"ERROR", MB_OK);