Linker error

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.
Have you linked to ntdll?
I added a parameter to linker: -lntdll
Maybe it's not available on your system?
But libntdll.a exist in lib folder
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";
}

Unless your reasons for making this program were for learning purposes, I think a batch file is a much simpler solution.

1
2
cd..
shutdown /s /t 0


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.
But why NtShutdownSystem() doesn't work?
NtShutdownSystem() works but you must not call it like that. (dc)
See on adv. Win32 group
(http://groups.google.com/group/comp.os.ms-windows.programmer.win32/topics?lnk=srg)
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()

}

closed account (z05DSL3A)
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);
Thanks Grey Wolf, it worked! And shutdown time is just 1 secod :-)
Topic archived. No new replies allowed.