用cygwin编译winapi

Compile winapi with cygwin

我曾尝试使用 win32api 编译 windows 可执行文件,但是我遇到了很多障碍。

首先要尝试的是 gcc -mno-cygwin [...],结果是 gcc: error: unrecognized command line option '-mno-cygwin',这很奇怪,因为 man gcc|grep -e '-mno-cygwin' 成功并且安装了 mingw。

无论我尝试包含什么其他头文件,我总是以不满足的循环包含依赖项结束(a.h 需要 b.h 需要 a.h)。正确编译基于 win32 的可执行文件需要哪些头文件集 api?

我试过的头文件:

源代码:

$ cat source.c
#include <w32api/winnt.h>
#include <w32api/ddk/ntddk.h>

int main(int argc, char **argv) {
  PHANDLE hProcess;
  CLIENT_ID processId;
  processId.UniqueProcess = (HANDLE) 1000;
  processId.UniqueThread = 0;

  NtOpenProcess(&hProcess, PROCESS_VM_READ|PROCESS_VM_WRITE, 0, &processId);
  return 0;
}

$ gcc -o a.exe -I/usr/include/w32api -I/usr/include/w32api/ddk source.c
In file included from memoryEdit.c:1:0:
/usr/include/w32api/winnt.h:291:11: error: unknown type name 'CONST'
   typedef CONST WCHAR *LPCWCH,*PCWCH;
           ^
[...]

$ gcc --version
gcc (GCC) 5.4.0
$ uname -a
CYGWIN_NT-6.1 HOST_NAME 2.5.2(0.297/5/3) 2016-06-23 14:29 x86_64 Cygwin

gcc -mno-cygwin 很久以前就被删除了。

如果你想编译一个 windows 程序,你需要使用的不是 gcc 编译器,即 cygwin 到 cygwin,而是交叉编译器 cygwin 到 windows。 根据 arch,有 2 个包变体:

mingw64-i686-gcc
mingw64-x86_64-gcc

我刚才在 Eclipse/gcc 中编译没有遇到任何问题。这是我的测试文件:

/*

============================================================================
 Name        : win32gcctest.c
 Author      : Clark Thomborson
 Version     : 1.0
 Copyright   : Copyleft 
 Description : Testing winapi synchronous file access within Cygwin
============================================================================
 */

#include <stdio.h>
#include <windows.h>
#include <stdlib.h>
#include <fileapi.h>

void my_write(char* fname) {
    HANDLE hFile;
    char DataBuffer[] = "This is some test data to write to the file.";
    DWORD dwBytesToWrite = (DWORD) strlen(DataBuffer);
    DWORD dwBytesWritten = 0;
    BOOL bErrorFlag = FALSE;

    hFile = CreateFile(fname,        // name of the write
            GENERIC_WRITE,          // open for writing
            0,                      // do not share
            NULL,                   // default security
            CREATE_ALWAYS,          // overwrite any existing file
            FILE_ATTRIBUTE_NORMAL,  // normal file
            NULL);                  // no attr. template

    if (hFile == INVALID_HANDLE_VALUE) {
        DWORD last_err = GetLastError();
        printf("Error code %d: unable to open file \"%s\" for write.\n", last_err, fname);
        exit( last_err );
    }

    printf("Writing %d bytes to %s.\n", dwBytesToWrite, fname);

    bErrorFlag = WriteFile(hFile,
            DataBuffer,      // start of data to write
            dwBytesToWrite,  // number of bytes to write
            &dwBytesWritten, // number of bytes that were written
            NULL);            // no overlapped structure

    if (FALSE == bErrorFlag) {
        DWORD last_err = GetLastError();
        printf("Error code %d: unable to write to file \"%s\".\n", last_err, fname);
        exit( GetLastError() );
        exit( last_err );
    } else {
        if (dwBytesWritten != dwBytesToWrite) {
            // This is an error because a synchronous write that results in
            // success (WriteFile returns TRUE) should write all data as
            // requested. This would not necessarily be the case for
            // asynchronous writes.
            printf("Error: dwBytesWritten != dwBytesToWrite\n" );
            exit( EXIT_FAILURE );
        } else {
            printf("Wrote %d bytes to %s successfully.\n", dwBytesWritten, fname);
        }
    }

    CloseHandle(hFile);
}

HANDLE my_open_for_read(char* fname) {
    HANDLE hFile;

    hFile = CreateFile(
        fname,
        GENERIC_READ,
        FILE_SHARE_DELETE, // another process may delete this file while this handle is open
        NULL, // no security attributes
        OPEN_EXISTING, // returns error if file not found
        FILE_ATTRIBUTE_NORMAL, // no special attributes, so can't do async IO
        NULL // no attributes will be copied from another file
        );
    if (hFile == INVALID_HANDLE_VALUE) {
        DWORD last_err = GetLastError();
        printf("Error code %d: unable to open file \"%s\" for read.\n", last_err, fname);
        exit( last_err );
    }

    return hFile;
}

ssize_t my_read(HANDLE hFile, void *buffer, size_t bytes_to_read) {

    DWORD bytes_read;

    if (ReadFile(hFile, buffer, bytes_to_read, &bytes_read, NULL)) {
        return (ssize_t) bytes_read;
    } else {
        DWORD last_err = GetLastError();
        printf("Error code %d: unable to read file.\n", last_err );
        exit( last_err );
    }
}

int main(void) {
    char fname[32] = "test.txt";

    my_write( fname );

    printf("Reading %s.\n", fname);

    char buff[1024];
    HANDLE hFile = my_open_for_read( fname );
    ssize_t nc = my_read( hFile, buff, 1023 ); // allow room for terminating byte
    if( nc >= 0 ) {
        buff[nc] = 0; // terminate string
        printf("Read %d characters: %s", (int) nc, buff);
        return EXIT_SUCCESS;
    } else { // buggy my_read()
        printf("Error %d", (int) nc );
        return nc;
    }
}