/* gpgcempr.c - Manager for GPG CE devices Copyright (C) 2010 Free Software Foundation, Inc. This file is part of Assuan. Assuan is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. Assuan is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, see . */ #define _WIN32_WCE 0x0500 #include #include #define PGM "gpgcemgr" #define GPGCEDEV_KEY_NAME L"Drivers\\GnuPG_Device" #define GPGCEDEV_DLL_NAME L"gpgcedev.dll" #define GPGCEDEV_PREFIX L"GPG" static int install (void) { HKEY handle; DWORD disp, dw; if (RegCreateKeyEx (HKEY_LOCAL_MACHINE, GPGCEDEV_KEY_NAME, 0, NULL, 0, KEY_WRITE, NULL, &handle, &disp)) { fprintf (stderr, PGM": error creating registry key: rc=%d\n", (int)GetLastError ()); return 1; } RegSetValueEx (handle, L"dll", 0, REG_SZ, (void*)GPGCEDEV_DLL_NAME, sizeof (GPGCEDEV_DLL_NAME)); RegSetValueEx (handle, L"prefix", 0, REG_SZ, (void*)GPGCEDEV_PREFIX, sizeof (GPGCEDEV_PREFIX)); dw = 1; RegSetValueEx (handle, L"Index", 0, REG_DWORD, (void*)&dw, sizeof dw); RegCloseKey (handle); fprintf (stderr, PGM": registry key created\n"); return 0; } static int deinstall (void) { int result = 0; HANDLE shd; DEVMGR_DEVICE_INFORMATION dinfo; memset (&dinfo, 0, sizeof dinfo); dinfo.dwSize = sizeof dinfo; shd = FindFirstDevice (DeviceSearchByLegacyName, L"GPG1:", &dinfo); if (shd == INVALID_HANDLE_VALUE) { if (GetLastError () == 18) fprintf (stderr, PGM": device not found\n"); else { fprintf (stderr, PGM": FindFirstDevice failed: rc=%d\n", (int)GetLastError ()); result = 1; } } else { fprintf (stderr, PGM": ActivateDevice handle is %p\n", dinfo.hDevice); if (dinfo.hDevice && dinfo.hDevice != INVALID_HANDLE_VALUE) { if (!DeactivateDevice (dinfo.hDevice)) { fprintf (stderr, PGM": DeactivateDevice failed: rc=%d\n", (int)GetLastError ()); result = 1; } else fprintf (stderr, PGM": DeactivateDevice succeeded\n"); } FindClose (shd); } return result; } /* Kudos to Scott Seligman for his work on the reverse engineering. */ struct htc_sensor_s { SHORT tilt_x; // From -1000 to 1000 (about), 0 is flat SHORT tilt_y; // From -1000 to 1000 (about), 0 is flat SHORT tilt_z; // From -1000 to 1000 (about) DWORD angle_x; // 0 .. 359 DWORD angle_y; // From 0 to 359 DWORD orientation; // 0.. 5? DWORD unknown; // Handle? }; typedef struct htc_sensor_s *htc_sensor_t; static HANDLE (WINAPI *HTCSensorOpen) (DWORD); static void (WINAPI *HTCSensorClose) (HANDLE); static DWORD (WINAPI *HTCSensorGetDataOutput) (HANDLE, htc_sensor_t); static int load_sensor_api (void) { static HMODULE dll_hd; if (dll_hd) return 0; dll_hd = LoadLibrary (L"HTCSensorSDK.dll"); if (!dll_hd) { fprintf (stderr, PGM": error loading sensor DLL: rc=%d\n", (int)GetLastError ()); return 1; } HTCSensorOpen = (void*)GetProcAddress (dll_hd, L"HTCSensorOpen"); if (HTCSensorOpen) HTCSensorClose = (void*)GetProcAddress (dll_hd, L"HTCSensorClose"); if (HTCSensorClose) HTCSensorGetDataOutput = (void*) GetProcAddress (dll_hd, L"HTCSensorGetDataOutput"); if (!HTCSensorGetDataOutput) { fprintf (stderr, PGM": error loading function from sensor DLL: rc=%d\n", (int)GetLastError ()); CloseHandle (dll_hd); return 1; } return 0; } static int gravity (void) { int rc; HANDLE sensor; struct htc_sensor_s lastdata; struct htc_sensor_s data; rc = load_sensor_api (); if (rc) return rc; sensor = HTCSensorOpen (1 /* tilt sensor */); if (!sensor || sensor == INVALID_HANDLE_VALUE) { fprintf (stderr, PGM": error opening gravity sensor: rc=%d\n", (int)GetLastError ()); HTCSensorClose (sensor); return 1; } memset (&lastdata, 0, sizeof lastdata); while (HTCSensorGetDataOutput (sensor, &data)) { if (lastdata.tilt_x/10 != data.tilt_x/10 || lastdata.tilt_y/10 != data.tilt_y/10 || lastdata.tilt_z/10 != data.tilt_z/10 || lastdata.angle_x/5 != data.angle_x/5 || lastdata.angle_y/5 != data.angle_y/5 || lastdata.orientation != data.orientation) { lastdata = data; printf ("tilt: x=%-5d y=%-5d z=%-5d " "angle: x=%-3d y=%-3d " "ori: %d\n", (int)data.tilt_x, (int)data.tilt_y, (int)data.tilt_z, (int)data.angle_x, (int)data.angle_y, (int)data.orientation); } Sleep (200); } fprintf (stderr, PGM": reading sensor data failed: rc=%d\n", (int)GetLastError ()); HTCSensorClose (sensor); return 0; } /* No GPD1 device on the HTC Touch Pro 2. */ # if 0 static int gps_raw (void) { HANDLE hd; char buffer[1000]; unsigned long nread; int count; hd = CreateFile (L"GPD1:", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hd == INVALID_HANDLE_VALUE) { fprintf (stderr, PGM": can't open `GPD1': rc=%d\n", (int)GetLastError ()); return 1; } fprintf (stderr, PGM": GPS device successfully opened\n"); for (count=0; count < 100; count++) { if (!ReadFile (hd, buffer, sizeof buffer-1, &nread, NULL)) { fprintf (stderr, PGM": error reading `GPD1': rc=%d\n", (int)GetLastError ()); CloseHandle (hd); return 1; } buffer[nread-1] = 0; fputs (buffer, stdout); } CloseHandle (hd); return 0; } #endif /* Untested samples for CE6. */ #if 0 static int gps (void) { HANDLE hd; GPS_POSITION pos; hd = GPSOpenDevice (NULL, NULL, NULL, 0); if (hd == INVALID_HANDLE_VALUE) { fprintf (stderr, PGM": GPSOpenDevice failed: rc=%d\n", (int)GetLastError ()); return 1; } fprintf (stderr, PGM": GPS device successfully opened\n"); if (GPSGetPosition (hd, &pos, 2000, 0)) { fprintf (stderr, PGM": GPSGetPosition failed: rc=%d\n", (int)GetLastError ()); GPSCloseDevice (hd); return 1; } GPSCloseDevice (hd); return 0; } #endif int main (int argc, char **argv) { int result = 0; if (argc > 1 && !strcmp (argv[1], "--register")) result = install (); else if (argc > 1 && !strcmp (argv[1], "--deactivate")) result = deinstall (); else if (argc > 1 && !strcmp (argv[1], "--activate")) { /* This is mainly for testing. The activation is usually done right before the device is opened. */ if (ActivateDevice (GPGCEDEV_DLL_NAME, 0) == INVALID_HANDLE_VALUE) { fprintf (stderr, PGM": ActivateDevice failed: rc=%d\n", (int)GetLastError ()); result = 1; } else fprintf (stderr, PGM": device activated\n"); } else if (argc > 1 && !strcmp (argv[1], "--gravity")) result = gravity (); /* else if (argc > 1 && !strcmp (argv[1], "--gps")) */ /* result = gps (); */ else { fprintf (stderr, "usage: " PGM " --register|--deactivate|--activate\n"); result = 1; } fflush (stdout); fflush (stderr); Sleep (1000); return result; }