dimanche 12 juillet 2009

Runit


It may be interesting to run any program on a GPS device...

#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <windows.h>

#define prog_name TEXT("runit")
/*
** debug boxes
*/
void msg(char *str1, char *str2)
{
static char txtbuf[512];
static wchar_t wtxtbuf[512];

sprintf(txtbuf, "%s %s (GetLastError()=%ld)", str1, str2, GetLastError());
mbstowcs(&wtxtbuf[0], &txtbuf[0], strlen(txtbuf)+1);
MessageBox(0, &wtxtbuf[0], prog_name, MB_OK);
}
/*
** transform ASCII string into 'wide char string' and bufferize
*/
wchar_t *mylstr(char *cp)
{
int len;
wchar_t *wcp;
char *cp1, *cp2;
char buf[256];

for (cp1 = buf, cp2 = cp;((*cp1 = *cp2) != '\0') && ((cp1 - &buf[0]) < sizeof(buf)); cp1++, cp2++)
{
if (*cp1 == '/')
*cp1 = '\\';
}
len = strlen(cp)+1;
if ((wcp = (wchar_t*)malloc(len * sizeof(wchar_t))) == NULL)
{
msg("mylstr():Can't malloc()", "");
exit(0);
}
mbstowcs(wcp, buf, len);
return(wcp);
}

/*===================================================================*/
/* Debug module
** to write debug text into flash
*/
char *DBG_fname="\\SDMMC\\debug.txt";
FILE *DBG_stream;
int DBG_init()
{
if ((DBG_stream=fopen(DBG_fname, "a+")) == NULL)
{
msg("Can't fopen()", DBG_fname);
return(0);
}
fprintf(DBG_stream, "===== New log =====\n");
return(1);
}
int DBG_close()
{
return(fclose(DBG_stream));
}
int DBG_write(char *buf, int len)
{
if (fwrite(buf, 1, len, DBG_stream) != len)
msg("Can't write DBG_stream", DBG_fname);
return(len);
}
/*===================================================================*/
#define BUF_SIZE 512
/*
** run down the file tree and insert .exe files into the listbox
*/
int find_exe(FILE *fp, HWND hlistp, char *dir_name)
{
DIR *dirp;
struct dirent *direntp;
char buf[BUF_SIZE];
int len0;

len0 = strlen(dir_name);
if ((dirp = opendir(dir_name)) == NULL)
{ // probably a simple file...
if ((len0 > 4) && (strcmp(&dir_name[len0-4], ".exe") == 0))
{
SendMessage(hlistp, LB_ADDSTRING, 0, (LPARAM)mylstr(dir_name));
}
return(0);
}
while ((direntp = readdir(dirp)) != NULL)
{
direntp->d_name[direntp->d_namlen] = '\0'; /* to be sure */
if (strcmp(direntp->d_name, "..") && strcmp(direntp->d_name, "."))
{
if ((len0 + strlen(direntp->d_name)) < (BUF_SIZE-2))
{
if (dir_name[0] == '/' && dir_name[1] == '\0')
sprintf(buf, "/%s", direntp->d_name); /* no double-slash */
else sprintf(buf, "%s/%s", dir_name, direntp->d_name);
find_exe(fp, hlistp, buf);
}
else {
fprintf(fp, "OVERFLOW %s/%s", dir_name, direntp->d_name);
return(0);
}
}
}
closedir(dirp);
return(1);
}
/*===================================================================*/
// from http://www.siteduzero.com/tutoriel-3-8778-apprentissage-de-l-api-windows.html?all=1#ss_part_8698
HINSTANCE instance;

#define ID_LIST_FILES 110
#define ID_BUTTON_EXEC 111

HWND hList1;

VOID MainWin_init(HWND hMainWin)
{ // http://msdn.microsoft.com/en-us/library/ms960010.aspx
// http://www.xs4all.nl/~rjg70/vbapi/ref/msgc.html#listboxes
hList1=CreateWindow(
L"LISTBOX",
L"",
WS_CHILD|WS_VISIBLE|WS_VSCROLL,
10,10,
160,80,
hMainWin,
(HMENU)ID_LIST_FILES,
instance,
NULL);

CreateWindow(
L"BUTTON",
L"Execute",
WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,
10,100,
70,20,
hMainWin,
(HMENU)ID_BUTTON_EXEC,
instance,
NULL);
}
PROCESS_INFORMATION ProcessInformation;

VOID Doit(HWND hMainWin,UINT message,WPARAM wParam, LPARAM lParam)
{
WCHAR lpText[256];
LRESULT lRes;
UINT iId = LOWORD(wParam);
UINT iCode = HIWORD(wParam);
HWND hCtl = (HWND)lParam;

switch (iId)
{
case ID_LIST_FILES:
break;

case ID_BUTTON_EXEC:
if ((lRes = SendMessage(hList1, LB_GETCURSEL, 0, 0)) == LB_ERR)
{
MessageBox(hMainWin, L"Nothing selected", L"Abort!", MB_OK);
return;
}
SendMessage(hList1, LB_GETTEXT, (WPARAM)lRes, (LPARAM)lpText);
if (!CreateProcess(lpText, lpText, NULL, NULL, FALSE, 0, NULL, NULL, NULL, &ProcessInformation))
MessageBox(hMainWin, lpText, L"Failed", MB_OK);
else MessageBox(hMainWin, lpText, L"Success", MB_OK);

break;

default:
break;
}
}
LRESULT CALLBACK MainWin_do(HWND hMainWin, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CREATE:
MainWin_init(hMainWin);
return(0);
break;

case WM_COMMAND:
Doit(hMainWin, msg, wParam, lParam);
return(0);
break;

case WM_DESTROY:
PostQuitMessage(0);
return(0);
break;

default:
return(DefWindowProc(hMainWin, msg, wParam, lParam));
break;
}
}

int WinMain (HINSTANCE thisInst, HINSTANCE prevInst,
LPWSTR cmdLine, int displayMode)
{
HWND hMainWin;
MSG msg;
WNDCLASS windowClass;

DBG_init();
instance = thisInst;

windowClass.style = CS_DBLCLKS;// to catch double-clics
windowClass.lpfnWndProc = MainWin_do;
windowClass.cbClsExtra = 0;
windowClass.cbWndExtra = 0;
windowClass.hInstance = NULL;
windowClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
windowClass.hbrBackground = (HBRUSH)(1 + COLOR_BTNFACE);
windowClass.lpszMenuName = NULL;
windowClass.lpszClassName = L"Wclass";

if(!RegisterClass(&windowClass))
return FALSE;

hMainWin=CreateWindow(
L"Wclass",
L"Run It",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,CW_USEDEFAULT,
240,200,
NULL,
NULL,
thisInst,
NULL);

if (!hMainWin)
return FALSE;

ShowWindow(hMainWin, displayMode);
UpdateWindow(hMainWin);

find_exe(DBG_stream, hList1, "/");
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
DBG_close();
return msg.wParam;
}


On the connex, we can now use the Windows explorer to launch gosm_arm.exe :