Linker error
May 27, 2009 at 3:24pm UTC
Code:
1 2 3 4 5 6 7 8 9
#include <windows.h>
#include <ntdll.h>
int main()
{
SHUTDOWN_ACTION sha;
sha=ShutdownNoReboot;
NtShutdownSystem(sha);
}
when i compile this i get error about undefined reference. What's wrong here?
I'm using Dev-C++ with mingw compiler.
May 27, 2009 at 3:40pm UTC
Have you linked to ntdll?
May 27, 2009 at 3:53pm UTC
I added a parameter to linker: -lntdll
May 27, 2009 at 4:00pm UTC
Maybe it's not available on your system?
May 27, 2009 at 4:15pm UTC
But libntdll.a exist in lib folder
May 27, 2009 at 6:24pm UTC
That function isn't documented.
You should use WindowsExitEx().
You have to adjust your privileges first, though, so it's a little bulky.
Here's a chunk of code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
#include <windows.h>
#include <iostream>
#include <string>
BOOL shutDown()
{
HANDLE hToken;
TOKEN_PRIVILEGES priv;
// Adjust privileges
if ( !OpenProcessToken ( GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken ))
return FALSE;
LookupPrivilegeValue ( NULL, SE_SHUTDOWN_NAME,
&priv.Privileges[0].Luid );
priv.PrivilegeCount = 1;
priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges ( hToken, FALSE, &priv, 0,
(PTOKEN_PRIVILEGES)NULL, 0);
if ( GetLastError() != ERROR_SUCCESS )
return FALSE;
// Shutdown system
return ExitWindowsEx ( EWX_SHUTDOWN | EWX_FORCE, 0 );
}
int main()
{
std::string ans;
std::cout << "Shutdown? " ;
std::getline ( std::cin, ans );
if ( ans != "yes" ) return 0;
if ( !shutDown() )
std::cout << "Can't shut down\n" ;
}
May 28, 2009 at 2:24am UTC
Unless your reasons for making this program were for learning purposes, I think a batch file is a much simpler solution.
ps. You might not need the "cd..", but for some reason on my system if I don't have it in there my computer outputs "shutdown /s /t 0" infinitely and never actually shuts down.
May 28, 2009 at 11:51am UTC
But why NtShutdownSystem() doesn't work?
May 28, 2009 at 4:00pm UTC
May 29, 2009 at 3:35pm UTC
Now i'm totally confused. I decided to access function directly from dll but it doesn't work.
1 2 3 4 5 6 7 8 9 10 11 12 13
int main()
{
typedef int (__cdecl *MYPROC)(SHUTDOWN_ACTION);
MYPROC h;
SHUTDOWN_ACTION sha;
sha=ShutdownReboot;
HINSTANCE hi;
hi=GetModuleHandle("ntdll.dll" );
h=(MYPROC)GetProcAddress(hi,"NtShutdownSystem" );
if (h!=NULL) cout <<"success" ;
(h)(sha); //calling NtShutdownSystem()
}
May 29, 2009 at 3:50pm UTC
Have you got the privileges to call NtShutdownSystem?
NtShutdownSystem is undocumented, but I have found the following that may help:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
HANDLE hToken;
if (OpenProcessToken(GetCurrentProcess(),
TOKEN_QUERY|TOKEN_ADJUST_PRIVILEGES, &hToken))
{
TOKEN_PRIVILEGES tkp;
LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, NULL, 0);
CloseHandle(hToken);
}
NtShutdownSystem(ShutdownNoReboot);
May 29, 2009 at 4:17pm UTC
Thanks Grey Wolf, it worked! And shutdown time is just 1 secod :-)
Topic archived. No new replies allowed.