Win API

常见的基本数据类型

在 Windows API 编程中,通常会使用一些约定俗成的变量命名来表示特定的含义:

  • HINSTANCE​/HMODULE​: 表示一个动态链接库(DLL)或可执行文件的句柄
  • HWND​: 表示一个窗口句柄
  • DWORD​/UINT​: 表示 32 位无符号整数
  • LPSTR​/LPCSTR​: 表示指向 null 结尾的字符串的指针

CreateThread​函数

CreateThread​ 是 Windows API 中的一个函数,它用于创建一个新的线程。

1
2
3
4
5
6
7
8
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes,
SIZE_T dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
__drv_aliasesMem LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId
);

参数说明:

  1. lpThreadAttributes​: 用于指定新线程的安全属性,通常设置为 NULL​ 使用默认值。
  2. dwStackSize​: 指定新线程的栈大小,如果设置为 0,则使用默认值。
  3. lpStartAddress​: 指向线程入口函数的指针,这个函数是线程的起点。
  4. lpParameter​: 传递给线程入口函数的参数,可以是任何类型的数据。
  5. dwCreationFlags​: 用于指定线程的创建选项,如 CREATE_SUSPENDED​ 可以创建一个暂停状态的线程。
  6. lpThreadId​: 用于接收新创建线程的 ID,可以为 NULL​。

该函数的返回值是一个 HANDLE​ 类型,它表示新创建的线程句柄。如果创建失败,返回值为 NULL​。

GetTickCount​函数

GetTickCount​ 是 Windows API 中的一个函数,它用于获取系统启动以来经过的毫秒数。

1
DWORD GetTickCount(void);

该函数没有任何参数,返回值是一个 DWORD​ 类型的值,表示系统启动以来经过的毫秒数。

这个函数通常用于以下场景:

  1. 性能测量和监控:计算某个操作或事件的持续时间,比如测试函数的执行时间、计算程序的总运行时间等。
  2. 定时和延迟操作:通过比较当前时间和之前保存的时间戳,可以实现定期执行任务或延迟一定时间后执行某个操作。
  3. 计算相对时间:不需要获取绝对的系统时间,只需要关心两个时间点之间的时间差。这对于某些时间敏感的应用程序很有用。

CreateNamedPipeA​函数

CreateNamedPipeA​ 是 Windows API 中用于创建命名管道的函数。命名管道是一种进程间通信机制,允许进程之间通过管道进行数据交换。

1
2
3
4
5
6
7
8
9
10
HANDLE WINAPI CreateNamedPipeA(
LPCSTR lpName,
DWORD dwOpenMode,
DWORD dwPipeMode,
DWORD nMaxInstances,
DWORD nOutBufferSize,
DWORD nInBufferSize,
DWORD nDefaultTimeOut,
LPSECURITY_ATTRIBUTES lpSecurityAttributes
);

各个参数的含义如下:

  1. lpName​: 指定要创建的命名管道的名称。管道名称以 \\\\.\\pipe\\​ 为前缀,后跟自定义的管道名称。
  2. dwOpenMode​: 指定管道的打开模式,如是否用于读取、写入或双向通信。
  3. dwPipeMode​: 指定管道的其他属性,如无阻塞模式、消息模式等。
  4. nMaxInstances​: 指定同时可以连接到管道的最大客户端数量。
  5. nOutBufferSize​: 指定管道的输出缓冲区大小(以字节为单位)。
  6. nInBufferSize​: 指定管道的输入缓冲区大小(以字节为单位)。
  7. nDefaultTimeOut​: 指定客户端连接超时时间(以毫秒为单位)。
  8. lpSecurityAttributes​: 指定管道的安全属性。

该函数返回一个 HANDLE​ 类型的句柄,表示创建的命名管道。如果创建失败,返回 INVALID_HANDLE_VALUE​。

创建命名管道后,可以使用 ConnectNamedPipe​ 函数来等待客户端连接,或使用 CreateFile​ 函数来连接到管道。

ConnectNamedPipe​函数

ConnectNamedPipe​ 是 Windows API 中用于连接到命名管道的函数。它允许客户端应用程序连接到由服务器应用程序创建的命名管道。

1
2
3
4
BOOL WINAPI ConnectNamedPipe(
HANDLE hNamedPipe,
LPOVERLAPPED lpOverlapped
);

参数说明:

  1. hNamedPipe​: 要连接的命名管道的句柄。这个句柄通常是由 CreateNamedPipeA​ 或 CreateNamedPipeW​ 函数返回的。
  2. lpOverlapped​: 指向一个 OVERLAPPED​ 结构体的指针。这个参数用于指定异步 I/O 操作。如果不需要异步 I/O,可以设置为 NULL​。

函数返回值:

  • 如果函数成功,返回值为 TRUE​。
  • 如果函数失败,返回值为 FALSE​。可以使用 GetLastError​ 函数获取错误代码。

WriteFile​函数

WriteFile​ 是 Windows API 中用于向文件或其他输出设备写入数据的函数。它可以用于向命名管道写入数据。

1
2
3
4
5
6
7
BOOL WINAPI WriteFile(
HANDLE hFile,
LPCVOID lpBuffer,
DWORD nNumberOfBytesToWrite,
LPDWORD lpNumberOfBytesWritten,
LPOVERLAPPED lpOverlapped
);

参数说明:

  1. hFile​: 要写入数据的文件或设备的句柄。对于命名管道,这通常是由 CreateNamedPipeA​ 或 CreateNamedPipeW​ 函数返回的句柄。
  2. lpBuffer​: 指向要写入的数据缓冲区的指针。
  3. nNumberOfBytesToWrite​: 要写入的字节数。
  4. lpNumberOfBytesWritten​: 指向一个 DWORD​ 变量的指针,用于接收实际写入的字节数。
  5. lpOverlapped​: 指向一个 OVERLAPPED​ 结构体的指针,用于指定异步 I/O 操作。如果不需要异步 I/O,可以设置为 NULL​。

函数返回值:

  • 如果函数成功,返回值为 TRUE​。
  • 如果函数失败,返回值为 FALSE​。可以使用 GetLastError​ 函数获取错误代码。

CloseHandle​ 函数

CloseHandle​ 函数是 Windows API 中用于关闭各种类型的内核对象句柄的函数。它可以用于关闭文件、管道、事件、互斥量等各种类型的句柄。

1
2
3
BOOL WINAPI CloseHandle(
HANDLE hObject
);

参数说明:

  • hObject​: 要关闭的内核对象的句柄。

函数返回值:

  • 如果函数成功,返回值为 TRUE​。
  • 如果函数失败,返回值为 FALSE​。可以使用 GetLastError​ 函数获取错误代码。

CreateFileA​函数

CreateFileA()​ 是 Windows API 中的一个函数,用于创建或打开文件。

1
2
3
4
5
6
7
8
9
HANDLE CreateFileA(
LPCSTR lpFileName,
DWORD dwDesiredAccess,
DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition,
DWORD dwFlagsAndAttributes,
HANDLE hTemplateFile
);
  1. lpFileName​: 指向要创建或打开的文件名的指针。这可以是一个文件路径。
  2. dwDesiredAccess​: 指定文件的访问模式,如读、写、读写等。可以使用预定义的标志位组合。
  3. dwShareMode​: 指定文件的共享模式,如允许其他进程读取、写入等。可以使用预定义的标志位组合。
  4. lpSecurityAttributes​: 指向描述新创建文件的安全属性的指针。通常传 NULL 使用默认值。
  5. dwCreationDisposition​: 指定如何创建或打开文件,比如创建新文件、打开现有文件、如果不存在则创建等。
  6. dwFlagsAndAttributes​: 指定附加的文件属性和标志,如文件类型、临时文件等。
  7. hTemplateFile​: 指向作为文件模板的现有文件的句柄。通常传 NULL。

该函数返回一个文件句柄(HANDLE)。如果创建或打开文件失败,返回 INVALID_HANDLE_VALUE。

ReadFile​函数

ReadFile()​ 是 Windows API 中的一个函数,用于从文件中读取数据。

1
2
3
4
5
6
7
BOOL ReadFile(
HANDLE hFile,
LPVOID lpBuffer,
DWORD nNumberOfBytesToRead,
LPDWORD lpNumberOfBytesRead,
LPOVERLAPPED lpOverlapped
);

各个参数的含义如下:

  1. hFile​: 要读取的文件的句柄。这通常是通过 CreateFileA()​ 或 CreateFileW()​ 函数获得的。
  2. lpBuffer​: 指向存储读取数据的缓冲区的指针。
  3. nNumberOfBytesToRead​: 要读取的字节数。
  4. lpNumberOfBytesRead​: 指向一个 DWORD 变量的指针,用于存储实际读取的字节数。
  5. lpOverlapped​: 指向一个 OVERLAPPED 结构体的指针,用于指定异步 I/O 操作。如果使用同步 I/O,则传 NULL。

该函数返回一个 BOOL 值,表示操作是否成功。如果成功,返回 TRUE;否则返回 FALSE,可以使用 GetLastError()​ 函数获取错误代码。

VirtualAlloc​函数

VirtualAlloc​ 函数是一个 Windows API 函数,用于在进程的虚拟地址空间中分配内存。

1
2
3
4
5
6
LPVOID WINAPI VirtualAlloc(
LPVOID lpAddress,
SIZE_T dwSize,
DWORD flAllocationType,
DWORD flProtect
);

参数说明:

  1. lpAddress​: 要分配的内存区域的起始地址。如果传递 NULL​,系统会自动确定分配的地址。

  2. dwSize​: 要分配的内存大小,单位是字节。

  3. flAllocationType​: 内存分配的类型,可以是以下值的组合:

    • MEM_COMMIT​: 提交指定内存区域的页面。
    • MEM_RESERVE​: 保留进程虚拟地址空间中的一个范围,但不分配实际的物理存储。
    • MEM_LARGE_PAGES​: 使用大页面大小分配内存。
  4. flProtect​: 分配的内存页面的访问权限,可以是内存保护常量之一。

返回值:
如果函数成功,返回分配的内存区域的起始地址;如果失败,返回 NULL​。

GetModuleHandleA​函数

GetModuleHandleA​ 是 Windows API 中的一个函数,用于获取指定模块的句柄。

1
2
3
HMODULE WINAPI GetModuleHandleA(
LPCSTR lpModuleName
);

参数说明:

  1. lpModuleName​: 要获取句柄的模块的名称。如果传入 NULL​,则返回调用进程的模块句柄。

返回值:

  • 如果函数成功,返回指定模块的句柄。
  • 如果函数失败,返回 NULL​。

GetProcAddress​函数

GetProcAddress​ 是 Windows API 中的一个函数,用于获取指定模块中导出函数的地址

1
2
3
4
FARPROC WINAPI GetProcAddress(
HMODULE hModule,
LPCSTR lpProcName
);

参数说明:

  1. hModule​: 包含要获取的函数的模块的句柄。可以通过 GetModuleHandleA​ 或 LoadLibraryA​ 函数获取。
  2. lpProcName​: 要获取的函数的名称。如果函数采用序号导出,则可以传入一个 WORD 类型的序号。

返回值:

  • 如果函数成功,返回指定函数的地址。
  • 如果函数失败,返回 NULL​。

VirtualProtect​函数

VirtualProtect​ 是一个 Windows API 函数,用于修改指定内存区域的访问保护属性。

1
2
3
4
5
6
BOOL WINAPI VirtualProtect(
LPVOID lpAddress,
SIZE_T dwSize,
DWORD flNewProtect,
PDWORD lpflOldProtect
);

参数说明:

  • lpAddress​: 要修改保护属性的内存区域的起始地址。

  • dwSize​: 要修改保护属性的内存区域的大小(以字节为单位)。

  • flNewProtect​: 新的内存区域保护属性。可以是以下值的组合:

    • PAGE_NOACCESS​: 内存区域不能访问。
    • PAGE_READONLY​: 内存区域可读。
    • PAGE_READWRITE​: 内存区域可读写。
    • PAGE_EXECUTE​: 内存区域可执行。
    • PAGE_EXECUTE_READ​: 内存区域可执行和读取。
    • PAGE_EXECUTE_READWRITE​: 内存区域可执行、读取和写入。
  • lpflOldProtect​: 指向一个 DWORD​ 变量的指针,用于接收修改前的内存区域保护属性。

函数返回值:

  • 成功返回 TRUE​。
  • 失败返回 FALSE​,可以调用 GetLastError​ 函数获取错误代码。