关于WINSOCK编程中需要注意的一点

    由于WINDOWS默认的通信模式为阻塞模式,所以在日后的编程中尽量采用多线程的方法,自己现在对非阻塞模式了解得不多,但我认为多线程应该是一种比较理想的方法,特别是在服务端的while循环中等待接收信息的时候,分线程来处理,防止进程停滞。

远程控制编程技术--关机操作的实现

二、关机操作的实现:
BOOL ExitWindowsEx(
  UINT uFlags,       // shutdown operation
  DWORD dwReserved   // reserved
);
(The ExitWindowsEx function either logs off the current user, shuts down the system, or shuts down and restarts the system. It sends the WM_QUERYENDSESSION message to all applications to determine if they can be terminated.)参数说明详见MSDN

 

 

DWORD GetVersion(VOID);
(The GetVersion function returns the current version number of the operating system. If the function succeeds, the return value is a DWORD value that contains the major and minor version numbers of the operating system in the low order word, and information about the operating system platform in the high order word.)
This function has been superseded by GetVersionEx, which is the preferred method for obtaining system version number information.

 

 

BOOL GetVersionEx(
  LPOSVERSIONINFO lpVersionInformation  //pointer to version information structure
);
lpVersionInformation
Pointer to an OSVERSIONINFO data structure that the function fills with operating system version information.
Before calling the GetVersionEx function, set the dwOSVersionInfoSize member of the OSVERSIONINFO data structure to sizeof(OSVERSIONINFO).

 

 

typedef struct _OSVERSIONINFO{
    DWORD dwOSVersionInfoSize;
    DWORD dwMajorVersion;
    DWORD dwMinorVersion;
    DWORD dwBuildNumber;
    DWORD dwPlatformId;
    TCHAR szCSDVersion[ 128 ];
} OSVERSIONINFO;

 


BOOL OpenProcessToken(
  HANDLE ProcessHandle,   // handle to process要修改访问权限的进程句柄
  DWORD DesiredAccess,   // desired access to process指定你要进行的操作类型
  PHANDLE TokenHandle   // pointer to handle of open access token返回访问令牌指针
);
(The OpenProcessToken function opens the access token associated with a process. 获得进程访问令牌的句柄)

 

 

HANDLE GetCurrentProcess(VOID);
(The GetCurrentProcess function returns a pseudohandle for the current process.)

 

 

BOOL AdjustTokenPrivileges(
  HANDLE TokenHandle,  // handle to token that contains privileges
  BOOL DisableAllPrivileges, // flag for disabling all privileges
  PTOKEN_PRIVILEGES NewState, // pointer to new privilege information
  DWORD BufferLength,  // size, in bytes, of the PreviousState buffer
  PTOKEN_PRIVILEGES PreviousState, // receives original state of changed privileges
  PDWORD ReturnLength  // receives required size of the PreviousState buffer
);
对获得的进程访问令牌权限进行修改。
第一个参数是访问令牌的句柄;第二个参数决定是进行权限修改还是除能(Disable)所有权限;第三个参数指明要修改的权限,是一个指向TOKEN_PRIVILEGES结构的指针,该结构包含一个数组,数据组的每个项指明了权限的类型和要进行的操作; 第四个参数是结构PreviousState的长度,如果PreviousState为空,该参数应为NULL;第五个参数也是一个指向TOKEN_PRIVILEGES结构的指针,存放修改前的访问权限的信息,可空;最后一个参数为实际PreviousState结构返回的大小。

 

 

typedef struct _TOKEN_PRIVILEGES { // tp
    DWORD PrivilegeCount;
    LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY];
} TOKEN_PRIVILEGES;

 

 

typedef struct _LUID_AND_ATTRIBUTES { // luaa
    LUID   Luid;
    DWORD  Attributes;
} LUID_AND_ATTRIBUTES;
第二个参数就指明了我们要进行的操作类型,有三个可选项: SE_PRIVILEGE_ENABLED、SE_PRIVILEGE_ENABLED_BY_DEFAULT、SE_PRIVILEGE_USED_FOR_ACCESS。要使能一个权限就指定Attributes为SE_PRIVILEGE_ENABLED。第一个参数就是指权限的类型,是一个LUID的值可通过另外一个API函数LookupPrivilegevalue得到。

 

 

BOOL LookupPrivilegeValue(
  LPCTSTR lpSystemName, // address of string specifying the system
  LPCTSTR lpName,  // address of string specifying the privilege
  PLUID lpLuid     // address of locally unique identifier
);
获得一个权限对应的LUID值。
第一个参数是系统的名称,如果是本地系统只要指明为NULL就可以了,第二个参数就是指明了权限的名称,如“SeDebugPrivilege”,第三个参数就是返回LUID的指针。

 


#define SE_BACKUP_NAME       TEXT("SeBackupPrivilege")
#define SE_RESTORE_NAME      TEXT("SeRestorePrivilege")
#define SE_SHUTDOWN_NAME   TEXT("SeShutdownPrivilege")
#define SE_DEBUG_NAME        TEXT("SeDebugPrivilege")
…… ……

 

示例代码: