// // File: // // Written by: David M. Stanhope [voip@fobbit.com] // // Fobbit Phone Windows Wrapper // // this is used just to build and test the gui // #define TESTING 1 #ifndef TESTING #include "vblast.h" static FILE *_log_fp = NULL ; static char *_log_name = "setup.log"; int debug_level = 0 ; #else // TESTING #include #define TXT_BUF_SIZE 512 #define sprintf wsprintf #define vsprintf wvsprintf #define VERSION_MAJOR 9 #define VERSION_MINOR 99 #define VERSION_DATE "TESTING" #endif // TESTING #include "resource.h" #include "direct.h" #define BIG_TXT_BUF_SIZE (TXT_BUF_SIZE * 4) LRESULT APIENTRY WndProc(HWND, UINT, WPARAM, LPARAM); void Init(HINSTANCE); // ---------------------------------------------------------------------------- #define ID_LOG 1 HINSTANCE g_hInst ; HWND w_main ; // main window HWND w_log ; #define W_BORDER 5 // width of border #define W_SCROLLBAR 5 // width of scrollbar #define W_LOG 660 // width of log window #define H_LOG 300 // height of log window #define X_LOCAL W_BORDER #define Y_LOCAL (W_BORDER + W_BORDER) #define W_LOCAL ((W_LOG / 2) - 3) // FUDGE? #define X_LOG W_BORDER // position #define Y_LOG (Y_LOCAL + W_BORDER) // position #define W_MAIN (W_BORDER + W_LOG + W_SCROLLBAR + W_BORDER) #define H_MAIN (Y_LOG + H_LOG + W_BORDER + 16) // FUDGE? // ---------------------------------------------------------------------------- void do_exit(void) { SendMessage(w_main, WM_CLOSE, 0, 0); while(1) { ; } } void x_exit(int x) { MessageBox(w_main, "Aborting Fobbit Phone Setup\n" "Check the log window for the reason", "Fatal Error", MB_OK | MB_ICONSTOP); do_exit(); } void msg_exit(char *msg, int icon) { MessageBox(w_main, msg, "Exiting", MB_OK | icon); do_exit(); } // ---------------------------------------------------------------------------- HWND create_listbox(HWND parent, int x, int y, int width, int height, int id) { return CreateWindow("ListBox", NULL, WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL | LBS_DISABLENOSCROLL | LBS_HASSTRINGS, x, y, width, height, parent, (HMENU) id, g_hInst, 0); } // ---------------------------------------------------------------------------- #include static void add_log1(char *s) { static int have = 0; while(have >= 1000) { SendMessage(w_log, LB_DELETESTRING, 0, 0); have--; } SendMessage(w_log, LB_ADDSTRING , 0, (LPARAM) (LPCSTR) s); SendMessage(w_log, LB_SETTOPINDEX, have, 0); have++; } static void add_log(char *s) { char *d, buf[TXT_BUF_SIZE]; int c, n; if(_log_fp) { fputs(s, _log_fp); fflush(_log_fp); } d = buf; n = 0; while(1) { c = *s++; if((c == '\n') || (c == '\r') || (c == '\0')) { if(n > 0) { *d++ = '\0'; add_log1(buf); } if(c == '\0') break; d = buf; n = 0; } else { *d++ = c; n++; } } } void logger(char *fmt, ...) { char buf[BIG_TXT_BUF_SIZE]; va_list ap; va_start(ap, fmt); vsprintf(buf, fmt, ap); va_end(ap); add_log(buf); } // ---------------------------------------------------------------------------- #define P(x) X_##x, Y_##x, W_##x, H_##x, ID_##x // build main window void create_top_level_window(HWND w) { #ifdef TESTING int i; char s_local[BIG_TXT_BUF_SIZE]; #endif w_log = create_listbox(w, P(LOG)); // use fixed width Font here since don't want to re-format all the messages SendMessage(w_log, WM_SETFONT, (WPARAM)GetStockObject(ANSI_FIXED_FONT), MAKELPARAM(TRUE, 0)); #ifdef TESTING for(i = 0; i < 500; i++) { sprintf(s_local, "LINE-%d", i); logger(s_local); } logger("0123456789012345678901234567890123456789" "012345678901234567890123456789012345678*"); #endif } // ---------------------------------------------------------------------------- extern unsigned char vb_exe_data[]; extern unsigned char vb_usb_inf_data[]; extern unsigned char Vb_Usb_sys_data[]; extern unsigned char ringback_723_data[]; extern unsigned char dialtone_723_data[]; extern unsigned char busy_723_data[]; extern unsigned char vb_ini_data[]; extern int vb_exe_size ; extern int vb_usb_inf_size ; extern int Vb_Usb_sys_size ; extern int ringback_723_size ; extern int dialtone_723_size ; extern int busy_723_size ; extern int vb_ini_size ; #define FX(x) x##_data, x##_size static char * build_path(char *base, char *name) { static char buf[TXT_BUF_SIZE]; if(base) { strcpy(buf, base); strcat(buf, "\\"); strcat(buf, name); } else { strcpy(buf, name); } return buf; } // return 1 if file exists, 0 if not static int check_exist(char *name) { if(GetFileAttributes(name) == ((DWORD) -1)) return 0; else return 1; } char * Show_WError(void) { LPVOID lpMsgBuf; static char buf[128]; DWORD err = GetLastError(); FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL); sprintf(buf, "%d:%s", err, lpMsgBuf); LocalFree(lpMsgBuf); return buf; } static void install_file(char *path, u_char *src, int len, char *msg) { HANDLE fd; DWORD wrote; int n; MSG(("%s \"%s\", (%d) bytes\n", msg, path, len)) fd = CreateFile(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if(fd == INVALID_HANDLE_VALUE) { ERR(("Open of <%s> Failed, Error(%s)\n", path, Show_Error())) x_exit(-1); } while(len > 0) { if(len > 512) { n = 512; } else { n = len; } if(WriteFile(fd, src, n, &wrote, NULL) == 0) { ERR(("Write(%s) Failed, Error: %s", path, Show_WError())) CloseHandle(fd); x_exit(-1); } len -= n; src += n; } CloseHandle(fd); } static void rename_file(char *old, char *new) { MSG(("Rename \"%s\" to \"%s\"\n", old, new)) if(rename(old, new) != 0) { ERR(("Failed Rename of <%s> to <%s>, Error(%s)\n", old, new, Show_Error())) x_exit(-1); } } #define BLOCK_LEN 1024 static int compare_file(HANDLE fd, u_char *src, int len) { int n; DWORD got; u_char cbuffer[BLOCK_LEN]; while(len > 0) { if(len > BLOCK_LEN) { n = BLOCK_LEN; } else { n = len; } if(ReadFile(fd, cbuffer, n, &got, NULL)) { if(got != ((DWORD)n)) { return 1; // read error so say don't match } } else { return 1; // read error so say don't match } if(memcmp(cbuffer, src, n) != 0) { return 1; // didn't match } src += n; len -= n; } return 0; // say match } static int require(char *msg, char *base, char *name, int reboot_if_create, u_char *src, int len) { HANDLE fd; char *path = build_path(base, name); fd = CreateFile(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if(fd == INVALID_HANDLE_VALUE) // file doesn't exist { if(msg) // only check { strcat(msg, "\""); strcat(msg, path); strcat(msg, "\" must be installed\n"); return 1; } else // do the actual work to install the file { install_file(path, src, len, "Installing"); return reboot_if_create; } return 0; // should never get here } // // if get here we know that the file exists // if((GetFileSize(fd, NULL) != ((DWORD)len)) || (compare_file(fd, src, len) != 0)) { CloseHandle(fd); if(msg) // only check { strcat(msg, "\""); strcat(msg, path); strcat(msg, "\" must be updated\n"); return 1; } else // do the actual work to install the file { SetFileAttributes(path, FILE_ATTRIBUTE_NORMAL); DeleteFile(path); install_file(path, src, len, "Updating"); return reboot_if_create; } return 0; // should never get here } CloseHandle(fd); return 0; } static int must_rm(char *msg, char *base, char *name, int reboot_if_remove) { char *path = build_path(base, name); if(check_exist(path) != 0) { if(msg) // only check { strcat(msg, "\""); strcat(msg, path); strcat(msg, "\" must be removed\n"); return 1; } else // do the actual work to remove the file { MSG(("Removing \"%s\"\n", path)) SetFileAttributes(path, FILE_ATTRIBUTE_NORMAL); DeleteFile(path); return reboot_if_remove; } } return 0; } #ifdef KEEP_FOR_FUTURE_REFERENCE #include "newdev.h" static void update_driver(void) { char path[256 + 1]; char *name_only; if(GetFullPathName("driver\\vb_usb.inf", 256, path, &name_only) > 0) { MSG(("Full Path For UpdateDriver (%s)\n", path)) UpdateDriverForPlugAndPlayDevices(w_main, "USB\\VID_1292&PID_0258", path, INSTALLFLAG_FORCE, NULL); } } #endif // if 'msg' is passed then check if file is ok and if not add to 'msg' with // info about what should be done. if 'msg' is null then actually do the work static int remove_or_install(char *msg, char *windir) { int todo; todo = must_rm(msg, windir, "inf\\oem0.inf" , 1); todo |= must_rm(msg, windir, "inf\\oem0.PNF" , 1); todo |= must_rm(msg, windir, "inf\\iausb.inf" , 1); todo |= must_rm(msg, windir, "inf\\iausb.PNF" , 1); todo |= must_rm(msg, windir, "system32\\drivers\\iausbsys.sys", 1); todo |= require(msg, windir, "inf\\vb_usb.inf" , 1, FX(vb_usb_inf )); todo |= require(msg, windir, "system32\\drivers\\vb_usb.sys" , 1, FX(Vb_Usb_sys )); todo |= require(msg, NULL , "driver\\vb_usb.inf" , 1, FX(vb_usb_inf )); todo |= require(msg, NULL , "driver\\vb_usb.sys" , 1, FX(Vb_Usb_sys )); todo |= require(msg, NULL , "sounds\\ringback.723" , 0, FX(ringback_723)); todo |= require(msg, NULL , "sounds\\dialtone.723" , 0, FX(dialtone_723)); todo |= require(msg, NULL , "sounds\\busy.723" , 0, FX(busy_723 )); todo |= require(msg, NULL , "vb.txt" , 0, FX(vb_ini )); todo |= require(msg, NULL , "vb.exe" , 0, FX(vb_exe )); // check if missing or need to upgrade the name if(check_exist("vb.ini") != 1) { if(check_exist("voip.ini") != 0) { if(msg) // only check { strcat(msg, "\"voip.ini\" must be renamed to \"vb.ini\"\n"); todo |= 1; } else // rename, no reboot required { rename_file("voip.ini", "vb.ini"); } } else { if(msg) // only check { strcat(msg, "\"vb.ini\" must be created\n"); todo |= 1; } else // create it, no reboot required { install_file("vb.ini", FX(vb_ini), "Installing"); } } } // see if need to upgrade but don't need to check for missing if((check_exist("vb.id") != 1) && (check_exist("voip.id") != 0)) { if(msg) // only check { strcat(msg, "\"voip.id\" must be renamed to \"vb.id\"\n"); todo |= 1; } else // rename, no reboot required { rename_file("voip.id", "vb.id"); } } return todo; } // ---------------------------------------------------------------------------- #define VB_TITLE_SETUP "VB SETUP - Fobbit Phone" static void vb_setup(void) { int r, todo; char *windir, *rootdir, msg[BIG_TXT_BUF_SIZE]; MSG(("VB Setup Starting\n")) if((windir = getenv("windir")) != NULL) { MSG(("Windir (%s)\n", windir)) } else { msg_exit("Variable 'windir' Not Set", MB_ICONSTOP); // does not return } if((rootdir = getenv("SystemRoot")) != NULL) { MSG(("SystemRoot (%s)\n", rootdir)) windir = rootdir; // use this instead if available } strcpy(msg, "Installation Not Complete\n"); // check if anything to do todo = remove_or_install(msg, windir); if(todo == 0) { MSG(("Setup Complete, Nothing to do!\n")) msg_exit("Setup Already Complete", MB_ICONINFORMATION); // does not return } MSG((msg)) strcat(msg, "Is it ok to complete the installation?\n"); r = MessageBox(w_main, msg, "Installation Check", MB_YESNO | MB_ICONQUESTION); if(r != IDYES) { msg_exit("Setup Not Complete", MB_ICONSTOP); // does not return } // if get here do the actual installation stuff _mkdir("sounds"); // insure directory exists _mkdir("driver"); // insure directory exists // do the work, see if need to reboot todo = remove_or_install(NULL, windir); if(todo) { MessageBox(w_main, "In Order To Complete The Installation\n" "Please Reboot The Computer\n" "Then Restart The Program", "Reboot Required", MB_OK | MB_ICONEXCLAMATION); do_exit(); // does not return } else { msg_exit("Setup Complete", MB_ICONINFORMATION); // does not return } } // ---------------------------------------------------------------------------- // application entry point int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR line, int CmdShow) { MSG msg; g_hInst = hInst; Init(hInst); #ifndef TESTING _log_fp = fopen(_log_name, "a"); #endif _beginthread((void *) vb_setup, 0, NULL); while(GetMessage(&msg,0,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return 0; } // initlize application void Init(HINSTANCE hInst) { WNDCLASS wc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hbrBackground = (HBRUSH) GetStockObject(LTGRAY_BRUSH); wc.hInstance = hInst; wc.hIcon = LoadIcon(hInst,MAKEINTRESOURCE(IDI_ICON1)); wc.hCursor = LoadCursor(NULL,IDC_ARROW); wc.lpfnWndProc = (WNDPROC) WndProc; wc.lpszClassName = "PPhone"; wc.lpszMenuName = 0; wc.style = CS_HREDRAW | CS_VREDRAW; RegisterClass(&wc); // // leave off WS_THICKFRAME and WS_MAXIMIZEBOX so can't change the // windows size, since for now not ready to handle that // w_main = CreateWindow("PPhone", VB_TITLE_SETUP, WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, W_MAIN, H_MAIN, 0, 0, hInst, 0); ShowWindow(w_main, SW_SHOW); UpdateWindow(w_main); } // main window callback function LRESULT APIENTRY WndProc(HWND w, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_DESTROY: PostQuitMessage(0); break; case WM_CREATE: create_top_level_window(w); break; default: return DefWindowProc(w, msg, wParam, lParam); } return 0; } // // The End! //