/* * browser.c - win32 interface to web browser * * Copyright (C) 2000 Stephen F. White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program (see the file "COPYING" for details); if * not, write to the Free Software Foundation, Inc., 675 Mass Ave, * Cambridge, MA 02139, USA. */ #include #include #include #include #define STARTUP_TIMEOUT 10000 typedef struct SBrowser { STABLE prefs; char *command; char *application; int pureVRML97; int useRemote; int xtypExecute; char *remoteCommand; char *topic; DWORD DDEInst; HSZ ourService; HSZ theirService; HSZ topicSZ; HSZ exitSZ; HANDLE hProcess; } SBrowser; static int browserLaunch(char* command , HANDLE* hProcess, const char *path, SWND wnd); static int browserConnect(SBROWSER browser); static int browserGoTo(SBROWSER browser, const char *path); static int bringToFront(SBROWSER browser); static char *fmtMsg(LPCTSTR lpszFormat, ...); static int getShellOpenCommand(SBROWSER browser, const char *extension); static void saveBrowserPreferences(SBROWSER browser); /*******************/ /* browser preview */ /*******************/ SBROWSER swBrowserInit(STABLE prefs) { SBrowser *browser = malloc(sizeof(SBrowser)); browser->prefs = prefs; browser->command = strdup(swGetPreference(prefs, "PreviewCommand", "")); browser->useRemote = swGetIntPreference(prefs, "PreviewUseRemote", TRUE); browser->pureVRML97 = swGetIntPreference(prefs, "PreviewPureVRML97", TRUE); browser->xtypExecute = swGetIntPreference(prefs, "XtypExecuteDDE", FALSE); browser->remoteCommand = strdup(swGetPreference(prefs, "PreviewRemoteCommand", "")); browser->application = strdup(swGetPreference(prefs, "PreviewApplication", "")); browser->topic = strdup(swGetPreference(prefs, "PreviewTopic", "")); if (!browser->command[0]) { getShellOpenCommand(browser, ".wrl"); } browser->hProcess = NULL; browser->DDEInst = 0L; return browser; } int swBrowserGetPureVRML97(SBROWSER browser) { return browser->pureVRML97; } void swBrowserGetSettings(SBROWSER browser, const char **command, int* pureVRML97, int *useRemote, int *xtypExecute, const char **remoteCommand, const char **application, const char **topic) { *command = browser->command; *pureVRML97 = browser->pureVRML97; *xtypExecute = browser->xtypExecute; *useRemote = browser->useRemote; *remoteCommand = browser->remoteCommand; *application = browser->application; *topic = browser->topic; } void swBrowserSetSettings(SBROWSER browser, const char *command, int pureVRML97, int useRemote, int xtypExecute, const char *remoteCommand, const char *application, const char *topic) { free(browser->command); free(browser->remoteCommand); free(browser->application); free(browser->topic); browser->command = strdup(command); browser->pureVRML97 = pureVRML97; browser->useRemote = useRemote; browser->xtypExecute = xtypExecute; browser->remoteCommand = strdup(remoteCommand); browser->application = strdup(application); browser->topic = strdup(topic); saveBrowserPreferences(browser); } static void saveBrowserPreferences(SBROWSER browser) { swSetPreference(browser->prefs, "PreviewCommand", browser->command); swSetIntPreference(browser->prefs, "PreviewPureVRML97", browser->pureVRML97); swSetIntPreference(browser->prefs, "PreviewUseRemote", browser->useRemote); swSetIntPreference(browser->prefs, "XtypExecuteDDE", browser->xtypExecute); swSetPreference(browser->prefs, "PreviewRemoteCommand", browser->remoteCommand); swSetPreference(browser->prefs, "PreviewApplication", browser->application); swSetPreference(browser->prefs, "PreviewTopic", browser->topic); } void swBrowserSetDefault(SBROWSER browser) { browser->command = strdup(""); browser->useRemote = TRUE; browser->pureVRML97 = TRUE; browser->xtypExecute = FALSE; browser->remoteCommand = strdup(""); browser->application = strdup(""); browser->topic = strdup(""); if (!browser->command[0]) { getShellOpenCommand(browser, ".wrl"); } browser->hProcess = NULL; browser->DDEInst = 0L; } void swBrowserPreview(SBROWSER browser, const char *path, SWND wnd) { if (browser->useRemote) { if (!browserGoTo(browser, path)) { if (browserLaunch(browser->command,browser->hProcess, NULL, wnd)) { browserGoTo(browser, path); } } } else { browserLaunch(browser->command,browser->hProcess, path, wnd); } } void swBrowserShutdown(SBROWSER browser) { saveBrowserPreferences(browser); if (browser->hProcess) { TerminateProcess(browser->hProcess, 1); CloseHandle(browser->hProcess); } free(browser->command); free(browser->remoteCommand); free(browser->application); free(browser->topic); if(browser->DDEInst != 0) { DdeNameService( browser->DDEInst, NULL, NULL, DNS_UNREGISTER); DdeFreeStringHandle( browser->DDEInst, browser->theirService); DdeFreeStringHandle( browser->DDEInst, browser->ourService); DdeFreeStringHandle( browser->DDEInst, browser->topicSZ); DdeUninitialize( browser->DDEInst ); } free(browser); } static char * fmtMsg(LPCTSTR lpszFormat, ...) { char *buf; LPTSTR lpszTemp; // format message into temporary buffer lpszTemp va_list argList; va_start(argList, lpszFormat); FormatMessage(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ALLOCATE_BUFFER, lpszFormat, 0, 0, (LPTSTR)&lpszTemp, 0, &argList); // assign lpszTemp into the resulting string and free the temporary buf = strdup(lpszTemp); LocalFree(lpszTemp); va_end(argList); return buf; } static int browserLaunch(char* command, HANDLE* hProcess, const char *path, SWND wnd) { STARTUPINFO startInfo; PROCESS_INFORMATION processInfo; int rc; char *s, *cmdline; if (path && path[0]) { if (strstr(command,"%s") == NULL) cmdline = fmtMsg(command, path); else { // expand %s to path char buf[1024]; mysnprintf(buf, 1023, command, path); cmdline = strdup(buf); } } else { cmdline = strdup(command); if (cmdline[0] == '"') { s = strchr(cmdline+1, '"'); if (s) (*(s+1)) = 0; } else { s = strchr(cmdline, ' '); if (s) *s = 0; } } memset(&startInfo, 0, sizeof(startInfo)); startInfo.cb = sizeof(STARTUPINFO); startInfo.dwFlags = STARTF_USESHOWWINDOW; startInfo.wShowWindow = SW_SHOWNA; if (CreateProcess(NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &startInfo, &processInfo) != 0) { WaitForInputIdle( processInfo.hProcess, STARTUP_TIMEOUT ); CloseHandle(processInfo.hThread); hProcess = processInfo.hProcess; rc = TRUE; } else { rc = FALSE; } free(cmdline); return rc; } static HDDEDATA DDECallback( UINT type, /* transaction type */ UINT fmt, /* clipboard data format */ HCONV hconv, /* handle of conversation */ HSZ hsz1, /* handle of string */ HSZ hsz2, /* handle of string */ HDDEDATA hData, /* handle of global memory object */ DWORD dwData1, /* transaction-specific data */ DWORD dwData2 /* transaction-specific data */ ) { return (HDDEDATA) 1; } static int browserGoTo(SBROWSER browser, const char *path) { char *buf; HSZ data; HCONV conv; HDDEDATA res; int timeout = 120; int rc = FALSE; if (browser->DDEInst == 0) { if (!browserConnect(browser)) return FALSE; } conv = DdeConnect( browser->DDEInst, browser->theirService, browser->topicSZ, NULL ); if( conv != NULL) { buf = fmtMsg( browser->remoteCommand, path ); data = DdeCreateStringHandle( browser->DDEInst, buf, CP_WINANSI ); if (browser->xtypExecute) res = DdeClientTransaction( buf, strlen(buf)+1, conv, 0L, 0, XTYP_EXECUTE, TIMEOUT_ASYNC, NULL); else res = DdeClientTransaction( NULL, 0, conv, data, CF_TEXT, XTYP_REQUEST, TIMEOUT_ASYNC, NULL); DdeDisconnect( conv); DdeFreeStringHandle( browser->DDEInst, data); free(buf); if (!browser->xtypExecute) bringToFront(browser); rc = TRUE; } return rc; } LONG queryValue(HKEY key, const char *subKey, char **result) { LONG size, rc; rc = RegQueryValue(key, subKey, NULL, &size); if (rc == ERROR_SUCCESS) { *result = (char *) malloc(size + 1); RegQueryValue(key, subKey, *result, &size); } else { *result = strdup(""); } return rc; } static int getShellOpenCommand(SBROWSER browser, const char *extension) { HKEY key; char *info; if (queryValue(HKEY_CLASSES_ROOT, extension, &info) != ERROR_SUCCESS) { return FALSE; } if (RegOpenKey(HKEY_CLASSES_ROOT, info, &key) != ERROR_SUCCESS) { free(info); return FALSE; } free(browser->command); free(browser->remoteCommand); free(browser->application); free(browser->topic); queryValue(key, "Shell\\Open\\command", &browser->command); queryValue(key, "Shell\\Open\\ddeexec", &browser->remoteCommand); browser->useRemote = browser->remoteCommand[0]; queryValue(key, "Shell\\Open\\ddeexec\\Application", &browser->application); queryValue(key, "Shell\\Open\\ddeexec\\Topic", &browser->topic); RegCloseKey(key); free(info); return TRUE; } static int browserConnect(SBROWSER browser) { int rc = FALSE; UINT initRes = DdeInitialize( &browser->DDEInst, (PFNCALLBACK) DDECallback, APPCLASS_STANDARD | CBF_FAIL_CONNECTIONS | CBF_SKIP_DISCONNECTS, 0 ); if (initRes == DMLERR_NO_ERROR) { browser->theirService = DdeCreateStringHandle( browser->DDEInst, browser->application, CP_WINANSI ); browser->ourService = DdeCreateStringHandle( browser->DDEInst, "Dune", CP_WINANSI ); browser->topicSZ = DdeCreateStringHandle( browser->DDEInst, browser->topic, CP_WINANSI ); DdeNameService( browser->DDEInst, browser->ourService, NULL, DNS_REGISTER); rc = TRUE; } return rc; } static int bringToFront(SBROWSER browser) { HSZ data, activate; HCONV conv; int timeout = 120; int rc = FALSE; activate = DdeCreateStringHandle( browser->DDEInst, "WWW_Activate", CP_WINANSI ); conv = DdeConnect( browser->DDEInst, browser->theirService, activate, NULL ); if( conv != NULL) { data = DdeCreateStringHandle( browser->DDEInst, "0xFFFFFFFF", CP_WINANSI ); DdeClientTransaction( NULL, 0, conv, data, CF_TEXT, XTYP_REQUEST, TIMEOUT_ASYNC, NULL); DdeFreeStringHandle( browser->DDEInst, data); DdeDisconnect( conv); rc = TRUE; } DdeFreeStringHandle( browser->DDEInst, activate); return rc; } void swRemoveFile(const char* filename) { unlink(filename); } /**********/ /* upload */ /**********/ typedef struct SUpload { STABLE prefs; char *commandline; char *htmlTag; char *password; } SUpload; SUPLOAD swUploadInit(STABLE prefs) { SUpload *upload = malloc(sizeof(SUpload)); upload->prefs = prefs; upload->commandline = strdup(swGetPreference(prefs, "UploadCommandLine", "")); upload->htmlTag = strdup(swGetPreference(prefs, "UploadHtmlTags", "")); /* do not read/store password for security reasons */ upload->password = malloc(1024); upload->password[0] = 0; VirtualLock(upload->password, 1024); return upload; } void swUploadGetSettings(SUPLOAD upload, const char **commandline, const char **htmlTag, const char **password) { *commandline = upload->commandline; *htmlTag = upload->htmlTag; *password = upload->password; } void swUploadSetSettings(SUPLOAD upload, const char *commandline, const char *htmlTag, const char *password) { free(upload->commandline); free(upload->htmlTag); upload->commandline = strdup(commandline); upload->htmlTag = strdup(htmlTag); if (password != NULL) mystrncpy_secure(upload->password, password, 1023); else upload->password[0] = 0; swSetPreference(upload->prefs, "UploadCommandLine", upload->commandline); swSetPreference(upload->prefs, "UploadHtmlTags", upload->htmlTag); /* do not read/store password for security reasons */ } int swHasUpload(SUPLOAD upload) { if (strlen(upload->commandline) > 0) return 1; else return 0; } char* swUpload(SUPLOAD upload, char *fileToUpload, SHBROWSER browser, SWND wnd) { static char uploadCommand[1024]; FILE *cmd; HANDLE f; struct _SECURITY_ATTRIBUTES security_attrib = { sizeof(SECURITY_ATTRIBUTES), NULL, // default security descriptor of the calling process FALSE }; DWORD bytesWritten; static htmlTags[1024]; int needPassword = 0; char *htmlpath = (char *) malloc(1024); htmlpath[0] = 0; if ((upload->password != NULL) && (strlen(upload->password) != 0)) if (strstr(upload->commandline, "%s") != NULL) if (strstr(strstr(upload->commandline, "%s") + 2, "%s") != NULL) needPassword = 1; // if commandline has two %s VirtualLock(uploadCommand, 1024); if (needPassword) mysnprintf(uploadCommand, 1023, upload->commandline, upload->password, fileToUpload); else mysnprintf(uploadCommand, 1023, upload->commandline, fileToUpload, ""); if (system(uploadCommand) != 0) { swMessageBox(wnd, "upload failed", "Upload failed", SW_MB_OK, SW_MB_WARNING); htmlpath[0] = 0; VirtualUnlock(uploadCommand, 1024); return htmlpath; } else VirtualUnlock(uploadCommand, 1024); swGetTempPath(htmlpath, ".dune_upload_reload", ".html", 1024); f = CreateFile(htmlpath, GENERIC_WRITE, // open for writing 0, // do not share &security_attrib, // security attributes CREATE_NEW, // do not overwrite existing FILE_ATTRIBUTE_NORMAL, // normal file NULL); // no attr. template if (f == -1) { char msg[1024]; mysnprintf(msg, 1023, "creation of new html file %s failed", htmlpath); swMessageBox(wnd, msg, "Upload reload error", SW_MB_OK, SW_MB_WARNING); htmlpath[0] = 0; return htmlpath; } if ((upload->password != NULL) && (strlen(upload->password) != 0)) mysnprintf(htmlTags, 1023, upload->htmlTag, upload->password); else mysnprintf(htmlTags, 1023, upload->htmlTag, ""); if (WriteFile(f, htmlTags, sizeof(htmlTags), &bytesWritten,NULL) ==0) { char msg[1024]; mysnprintf(msg, 1023, "write to html file %s failed", htmlpath); swMessageBox(wnd, msg, "Upload reload error", SW_MB_OK, SW_MB_WARNING); return htmlpath; } CloseHandle(f); helpBrowserGoTo(browser, htmlpath); return htmlpath; } void swUploadCleanupPasswd(SUPLOAD upload) { int i; for (i = 0; i < strlen(upload->password); i++) upload->password[i] = (char) 0; VirtualUnlock(upload->password, 1024); } /* help browser */ static void saveHelpBrowserPreferences(SHBROWSER browser); static int getShellOpenHelpCommand(SHBROWSER browser, const char *extension); static int helpBrowserGoTo(SHBROWSER browser, const char *path); static int helpBringToFront(SHBROWSER browser); static int helpBrowserConnect(SHBROWSER browser); typedef struct SHelpBrowser { STABLE prefs; char *helpCommand; char *helpRemoteCommand; char *helpApplication; char *helpTopic; char *helpUrl; char *vrmlUrl; DWORD DDEInst; HSZ ourService; HSZ theirService; HSZ topicSZ; HSZ exitSZ; HANDLE hProcess; } SHBrowser; SHBROWSER swHelpBrowserInit(STABLE prefs) { SHBrowser *browser = malloc(sizeof(SHBrowser)); browser->prefs = prefs; browser->helpCommand = strdup(swGetPreference(prefs, "HelpCommand", "")); browser->helpRemoteCommand = strdup(swGetPreference(prefs, "HelpRemoteCommand","")); browser->helpApplication = strdup(swGetPreference(prefs, "HelpApplication", "")); browser->helpTopic = strdup(swGetPreference(prefs, "HelpTopic", "")); browser->helpUrl = strdup(swGetPreference(prefs, "HelpUrl", HELP_URL )); browser->vrmlUrl = strdup(swGetPreference(prefs, "HelpVrmlNodes", VRML_NODES_URL)); if (browser->helpCommand[0]==' ') { getShellOpenHelpCommand(browser, ".htm"); } else if (!browser->helpCommand[0]) { getShellOpenHelpCommand(browser, ".htm"); } browser->hProcess = NULL; browser->DDEInst = 0L; return browser; } void swHelpBrowserGetSettings(SHBROWSER browser, const char **helpCommand, const char **helpRemoteCommand, const char **helpUrl, const char **vrmlUrl, const char **helpApplication, const char **helpTopic) { *helpCommand = browser->helpCommand; *helpRemoteCommand = browser->helpRemoteCommand; *helpUrl = browser->helpUrl; *vrmlUrl = browser->vrmlUrl; *helpApplication = browser->helpApplication; *helpTopic = browser->helpTopic; } void swHelpBrowserSetSettings(SHBROWSER browser, const char *helpCommand, const char *helpRemoteCommand, const char *helpUrl, const char *vrmlUrl, const char *helpApplication, const char *helpTopic) { free(browser->helpCommand); free(browser->helpRemoteCommand); free(browser->helpUrl); free(browser->vrmlUrl); free(browser->helpApplication); free(browser->helpTopic); browser->helpCommand = strdup(helpCommand); browser->helpRemoteCommand = strdup(helpRemoteCommand); browser->helpUrl = strdup(helpUrl); browser->vrmlUrl = strdup(vrmlUrl); browser->helpApplication = strdup(helpApplication); browser->helpTopic = strdup(helpTopic); saveHelpBrowserPreferences(browser); } static void saveHelpBrowserPreferences(SHBROWSER browser) { swSetPreference(browser->prefs, "HelpCommand", browser->helpCommand); swSetPreference(browser->prefs, "HelpRemoteCommand", browser->helpRemoteCommand); swSetPreference(browser->prefs, "HelpUrl", browser->helpUrl); swSetPreference(browser->prefs, "HelpVrmlNodes", browser->vrmlUrl); swSetPreference(browser->prefs, "HelpApplication", browser->helpApplication); swSetPreference(browser->prefs, "HelpTopic", browser->helpTopic); } void swHelpBrowserHTML(SHBROWSER browser, SWND wnd) { if (strstr(browser->helpCommand, "%s") != NULL) { char buf[4096]; mysnprintf(buf,4096, browser->helpCommand, browser->helpUrl); browserLaunch(buf, browser->hProcess, " ", wnd); } else if (!helpBrowserGoTo(browser, browser->helpUrl)) if (browserLaunch(browser->helpCommand, browser->hProcess, NULL, wnd)) { helpBrowserGoTo(browser, browser->helpUrl); } } void swHelpBrowserVRML(SHBROWSER browser, const char* selection_string, SWND wnd) { char* path=malloc(strlen(browser->vrmlUrl)+strlen(selection_string)+2); strcpy(path,browser->vrmlUrl); strcat(path,"#"); strcat(path,selection_string); if (strstr(browser->helpCommand, "%s") != NULL) { char buf[4096]; mysnprintf(buf,4096, browser->helpCommand, path); browserLaunch(buf, browser->hProcess, " ", wnd); } else if (!helpBrowserGoTo(browser, path)) { if (browserLaunch(browser->helpCommand, browser->hProcess, NULL, wnd)) { helpBrowserGoTo(browser, path); } } free(path); } void swHelpBrowserShutdown(SHBROWSER browser) { saveHelpBrowserPreferences(browser); if (browser->hProcess) { TerminateProcess(browser->hProcess, 1); CloseHandle(browser->hProcess); } free(browser->helpCommand); free(browser->helpRemoteCommand); free(browser->helpUrl); free(browser->vrmlUrl); free(browser->helpApplication); free(browser->helpTopic); if(browser->DDEInst != 0) { DdeNameService( browser->DDEInst, NULL, NULL, DNS_UNREGISTER); DdeFreeStringHandle( browser->DDEInst, browser->theirService); DdeFreeStringHandle( browser->DDEInst, browser->ourService); DdeFreeStringHandle( browser->DDEInst, browser->topicSZ); DdeUninitialize( browser->DDEInst ); } free(browser); } static int getShellOpenHelpCommand(SHBROWSER browser, const char *extension) { HKEY key; char *info; if (queryValue(HKEY_CLASSES_ROOT, extension, &info) != ERROR_SUCCESS) { return FALSE; } if (RegOpenKey(HKEY_CLASSES_ROOT, info, &key) != ERROR_SUCCESS) { free(info); return FALSE; } free(browser->helpCommand); free(browser->helpApplication); free(browser->helpTopic); queryValue(key, "Shell\\Open\\command", &browser->helpCommand); // queryValue(key, "Shell\\Open\\ddeexec", &browser->helpRemoteCommand); browser->helpRemoteCommand = strdup("%1"); queryValue(key, "Shell\\Open\\ddeexec\\Application", &browser->helpApplication); queryValue(key, "Shell\\Open\\ddeexec\\Topic", &browser->helpTopic); RegCloseKey(key); free(info); return TRUE; } static int helpBrowserGoTo(SHBROWSER browser, const char *path) { char *buf; HSZ data; HCONV conv; HDDEDATA res; int timeout = 120; int rc = FALSE; if (browser->DDEInst == 0) { if (!helpBrowserConnect(browser)) return FALSE; } conv = DdeConnect( browser->DDEInst, browser->theirService, browser->topicSZ, NULL ); if ( conv != NULL) { buf = fmtMsg( browser->helpRemoteCommand, path ); data = DdeCreateStringHandle( browser->DDEInst, buf, CP_WINANSI ); res = DdeClientTransaction( NULL, 0, conv, data, CF_TEXT, XTYP_REQUEST, TIMEOUT_ASYNC, NULL); DdeDisconnect( conv); DdeFreeStringHandle( browser->DDEInst, data); free(buf); helpBringToFront(browser); rc = TRUE; } return rc; } static int helpBringToFront(SHBROWSER browser) { HSZ data, activate; HCONV conv; int timeout = 120; int rc = FALSE; activate = DdeCreateStringHandle( browser->DDEInst, "WWW_Activate", CP_WINANSI ); conv = DdeConnect( browser->DDEInst, browser->theirService, activate, NULL ); if( conv != NULL) { data = DdeCreateStringHandle( browser->DDEInst, "0xFFFFFFFF", CP_WINANSI ); DdeClientTransaction( NULL, 0, conv, data, CF_TEXT, XTYP_REQUEST, TIMEOUT_ASYNC, NULL); DdeFreeStringHandle( browser->DDEInst, data); DdeDisconnect( conv); rc = TRUE; } DdeFreeStringHandle( browser->DDEInst, activate); return rc; } static int helpBrowserConnect(SHBROWSER browser) { int rc = FALSE; UINT initRes = DdeInitialize( &browser->DDEInst, (PFNCALLBACK) DDECallback, APPCLASS_STANDARD | CBF_FAIL_CONNECTIONS | CBF_SKIP_DISCONNECTS, 0 ); if (initRes == DMLERR_NO_ERROR) { browser->theirService = DdeCreateStringHandle( browser->DDEInst, browser->helpApplication, CP_WINANSI ); browser->ourService = DdeCreateStringHandle( browser->DDEInst, "Dune", CP_WINANSI ); browser->topicSZ = DdeCreateStringHandle( browser->DDEInst, browser->helpTopic, CP_WINANSI ); DdeNameService( browser->DDEInst, browser->ourService, NULL, DNS_REGISTER); rc = TRUE; } return rc; } /****************/ /* text editor */ /**************/ HANDLE hProcess; int swCheckRunningProcess(void) { DWORD ExitCode; if (GetExitCodeProcess(hProcess, &ExitCode)) if (ExitCode == STILL_ACTIVE) return 1; else { CloseHandle(hProcess); return 0; } else return 0; } int swCreateCheckableProcess(const char *cmdline) { STARTUPINFO startInfo; PROCESS_INFORMATION processInfo; SECURITY_ATTRIBUTES securityAttributes; int rc; memset(&startInfo, 0, sizeof(startInfo)); startInfo.cb = sizeof(STARTUPINFO); startInfo.dwFlags = STARTF_USESHOWWINDOW; startInfo.wShowWindow = SW_SHOWNA; memset(&securityAttributes, 0, sizeof(securityAttributes)); securityAttributes.nLength = sizeof(securityAttributes); securityAttributes.lpSecurityDescriptor = PROCESS_QUERY_INFORMATION; securityAttributes.bInheritHandle = TRUE; if (CreateProcess(NULL, cmdline, &securityAttributes, NULL, TRUE, 0, NULL, NULL, &startInfo, &processInfo) != 0) { WaitForInputIdle( processInfo.hProcess, STARTUP_TIMEOUT ); CloseHandle(processInfo.hThread); hProcess = processInfo.hProcess; rc = 0; } else { rc = GetLastError(); } return rc; } typedef struct STextedit { STABLE prefs; char *texteditCommand; char *texteditLinenumberOption; int texteditUseExtensionTxt; } STextedit; STEXTEDIT swTexteditInit(STABLE prefs) { STextedit *textedit = malloc(sizeof(STextedit)); textedit->prefs = prefs; if (getenv("WINEDITOR") != NULL) { textedit->texteditCommand = strdup(swGetPreference(prefs, "TextEditCommand", getenv("WINEDITOR"))); textedit->texteditLinenumberOption = strdup(swGetPreference(prefs, "TextEditLinenumberOption", "")); } else { textedit->texteditCommand = strdup(swGetPreference(prefs, "TextEditCommand", "C:\\WinNT\\system32\\edit.com")); textedit->texteditLinenumberOption = strdup(swGetPreference(prefs, "TextEditLinenumberOption", " ")); } textedit->texteditUseExtensionTxt = swGetIntPreference(prefs, "TextEditUseExtensionTxt", 1); return textedit; } void swTexteditGetSettingsUseExtensionTxt(STEXTEDIT textedit, int *texteditUseExtensionTxt) { *texteditUseExtensionTxt = textedit->texteditUseExtensionTxt; } void swTexteditGetSettings(STEXTEDIT textedit, const char **texteditCommand, const char **texteditLinenumberOption, int *texteditUseExtensionTxt, int *texteditAllowPopup) { *texteditCommand = textedit->texteditCommand; *texteditLinenumberOption = textedit->texteditLinenumberOption; *texteditUseExtensionTxt = textedit->texteditUseExtensionTxt; *texteditAllowPopup = 0; } void swTexteditSetSettings(STEXTEDIT textedit, const char *texteditCommand, const char *texteditLinenumberOption, int texteditUseExtensionTxt, int texteditAllowPopup) { free(textedit->texteditCommand); textedit->texteditCommand = strdup(texteditCommand); free(textedit->texteditLinenumberOption); textedit->texteditLinenumberOption = strdup(texteditLinenumberOption); textedit->texteditUseExtensionTxt = texteditUseExtensionTxt; swSetPreference(textedit->prefs, "TextEditCommand", textedit->texteditCommand); swSetPreference(textedit->prefs, "TextEditLinenumberOption", textedit->texteditLinenumberOption); swSetIntPreference(textedit->prefs, "TextEditUseExtensionTxt", textedit->texteditUseExtensionTxt); }