Custom error message when incorrect-architecture OCI.DLL is in PATH on Windows · Issue #49 · oracle/odpi (original) (raw)

When incorrect-architecture OCI.DLL is in the PATH and correct-architecture OCI.DLL isn't there, GetLastError() returns ERROR_BAD_EXE_FORMAT(%1 is not a valid Win32 application). How about custom error message saying "c:\full\path\of\OCI.DLL is 32-bit, which isn't available in x64 programs" or so in this case?
This will reduce issues such as oracle/node-oracledb#752.

  1. Search OCI.DLL as the step 1 in Custom error message when Visual Studio distributable package is not installed on Windows #48 (comment).
  2. If all OCI.DLLs are incorrect-architecture, create a custom error message. Otherwise use message from FormatMessage().

Architecture could be checked by nt_hdr->FileHeader.Machine in #48 (comment) or by the following function.

#include <windows.h>

static void print_arch(const char *name) { FILE *fp = fopen(name, "rb"); IMAGE_DOS_HEADER dos_hdr; IMAGE_NT_HEADERS nt_hdr;

if (fp == NULL) {
    printf("failed to open: %s\n", name);
    return;
}
fread(&dos_hdr, sizeof(dos_hdr), 1, fp);
if (dos_hdr.e_magic != IMAGE_DOS_SIGNATURE) {
    printf("invalid DOS signature: 0x%x\n", dos_hdr.e_magic);
    fclose(fp);
    return;
}
fseek(fp, dos_hdr.e_lfanew, SEEK_SET);
fread(&nt_hdr, sizeof(nt_hdr), 1, fp);
fclose(fp);
if (nt_hdr.Signature != IMAGE_NT_SIGNATURE) {
    printf("invalid NT signature: 0x%x\n", nt_hdr.Signature);
    return;
}
switch (nt_hdr.FileHeader.Machine) {
case IMAGE_FILE_MACHINE_I386:
    printf("architecture is x86.\n");
    break;
case IMAGE_FILE_MACHINE_AMD64:
    printf("architecture is x64.\n");
    break;
case IMAGE_FILE_MACHINE_IA64:
    printf("architecture is IA64.\n");
    break;
default:
    printf("invalid architecture: 0x%x\n", nt_hdr.FileHeader.Machine);
    break;
}

}