/* Copyright (c) 2000-2010, Dirk Krause All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above opyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Dirk Krause nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @file dkwftreg.c The dkwftreg program. This program set the PATH environment variable on windows system and add registry keys for explorer context menus. */ #include #include #include #line 51 "dkwftreg.ctr" /** Command: Install bmeps file context menu entries. */ #define CMD_BMEPS_FILE 1 /** Command: Install fig2vect file context menu entries. */ #define CMD_FIG2VECT_FILE 2 /** Command: Install tracecc GUI directory context menu entries. */ #define CMD_TRACECC_DIR 4 /** Command: Install bmeps GUI directory context menu entries. */ #define CMD_BMEPS_DIR 8 /** Command: Install fig2vect directory context menu entries. */ #define CMD_FIG2VECT_DIR 16 #include "dkstr.h" #include "dksf.h" #include /** Size for buffers. */ #define LINESIZE 1024 /** Exit status. */ static int exval = 0; /** Installation command. */ static int install_cmd = ( CMD_BMEPS_FILE | CMD_BMEPS_DIR | CMD_TRACECC_DIR | CMD_FIG2VECT_FILE | CMD_FIG2VECT_DIR ); /** Data to register context menu entries. */ typedef struct { char *tt; /**< Title text. */ char *cm; /**< Command to run. */ char *ar; /**< Command arguments. */ } FileAction; /** Default installation directory name. */ static char default_base_dir[] = { "C:\\Programme\\Krause" }; /** Buffer 1. */ static char buffer1[1024]; /** Buffer 2. */ static char buffer2[1024]; /** String -jar. */ static char part1[] = { "-jar " }; /** String: bmeps GUI jar file. */ static char part2[] = { "\\bin\\bmepsgui.jar" }; /** String: tracecc GUI jar file. */ static char part3[] = { "\\bin\\tracegui.jar" }; /** String: Argument 1. */ static char fn1[] = { "\"%1\"" }; /** String: Space. */ static char str_sp[] = { " " }; /** String: double quote. */ static char str_dq[] = { "\"" }; /** File context menu entries for bmeps. */ FileAction bmeps_actions[] = { { "bmeps: Convert to BoundingBox", "bmeps.exe", "-lbb -a \"%1\"" }, { "bmeps: Convert to EPS1", "bmeps.exe", "-leps1 -a \"%1\"" }, { "bmeps: Convert to EPS2", "bmeps.exe", "-leps2 -a \"%1\"" }, { "bmeps: Convert to EPS3", "bmeps.exe", "-leps3 -a \"%1\"" }, { "bmeps: Convert to PDF", "bmeps.exe", "-lpdf -a -A \"%1\"" }, { NULL, NULL, NULL } }; /** File context menu entries for bmeps (Fax to PDF). */ FileAction bmeps_fax_actions[] = { { "bmeps: Fax to PDF", "bmeps.exe", "-lfaxpdf -a -A \"%1\"" }, { NULL, NULL, NULL } }; /** Directory context menu entries for tracecc GUI. */ FileAction tracecc_actions[] = { { "Open in Tracecc GUI", "javaw.exe", NULL }, { NULL, NULL, NULL } }; /** Directory context menu entries for bmeps GUI. */ FileAction bmeps_dir_actions[] = { { "Open in Bmeps GUI", "javaw.exe", NULL }, { NULL, NULL, NULL } }; /** File context menu entries for fig2vect. */ FileAction fig2vect_actions[] = { { "fig2vect: Convert to EPS", "fig2vect.exe", "-leps -a --/log/stdout/level=none --/log/stderr/level=progress \"%1\"" }, { "fig2vect: Convert to PDF", "fig2vect.exe", "-lpdf -a --/log/stdout/level=none --/log/stderr/level=progress \"%1\"" }, { "fig2vect: Convert to EPS.TEX", "fig2vect.exe", "-leps.tex -a --/log/stdout/level=none --/log/stderr/level=progress \"%1\"" }, { "fig2vect: Convert to PDF.TEX", "fig2vect.exe", "-lpdf.tex -a --/log/stdout/level=none --/log/stderr/level=progress \"%1\"" }, { "fig2vect: Convert to TEX", "fig2vect.exe", "-ltex -a --/log/stdout/level=none --/log/stderr/level=progress \"%1\"" }, { "fig2vect: Convert to TEX FULL", "fig2vect.exe", "-ltex.full -a --/log/stdout/level=none --/log/stderr/level=progress \"%1\"" }, { "fig2vect: Convert to BB", "fig2vect.exe", "-lbb -a --/log/stdout/level=none --/log/stderr/level=progress \"%1\"" }, { "fig2vect: Convert to SVG", "fig2vect.exe", "-lsvg -a --/log/stdout/level=none --/log/stderr/level=progress \"%1\"" }, { NULL, NULL, NULL} }; /** Directory contenxt menu entries for fig2vect. */ FileAction fig2vect_directory_actions[] = { { "fig2vect: Convert to EPS", "fig2vect.exe", "-leps -a -m- --/log/stdout/level=none --/log/stderr/level=progress \"%1\"" }, { "fig2vect: Convert to PDF", "fig2vect.exe", "-lpdf -a -m- --/log/stdout/level=none --/log/stderr/level=progress \"%1\"" }, { "fig2vect: Convert to EPS.TEX", "fig2vect.exe", "-leps.tex -a -m- --/log/stdout/level=none --/log/stderr/level=progress \"%1\"" }, { "fig2vect: Convert to PDF.TEX", "fig2vect.exe", "-lpdf.tex -a -m- --/log/stdout/level=none --/log/stderr/level=progress \"%1\"" }, { "fig2vect: Convert to TEX", "fig2vect.exe", "-ltex -a -m- --/log/stdout/level=none --/log/stderr/level=progress \"%1\"" }, { "fig2vect: Convert to EPS FULL", "fig2vect.exe", "-ltex.full -a -m- --/log/stdout/level=none --/log/stderr/level=progress \"%1\"" }, { "fig2vect: Convert to BB", "fig2vect.exe", "-lbb -a -m- --/log/stdout/level=none --/log/stderr/level=progress \"%1\"" }, { "fig2vect: Convert to SVG", "fig2vect.exe", "-lsvg -a -m- --/log/stdout/level=none --/log/stderr/level=progress \"%1\"" }, { "fig2vect: Convert to EPS (make)", "fig2vect.exe", "-leps -a -m --/log/stdout/level=none --/log/stderr/level=progress \"%1\"" }, { "fig2vect: Convert to PDF (make)", "fig2vect.exe", "-lpdf -a -m --/log/stdout/level=none --/log/stderr/level=progress \"%1\"" }, { "fig2vect: Convert to EPS.TEX (make)", "fig2vect.exe", "-leps.tex -a -m --/log/stdout/level=none --/log/stderr/level=progress \"%1\"" }, { "fig2vect: Convert to PDF.TEX (make)", "fig2vect.exe", "-lpdf.tex -a -m --/log/stdout/level=none --/log/stderr/level=progress \"%1\"" }, { "fig2vect: Convert to TEX (make)", "fig2vect.exe", "-ltex -a -m --/log/stdout/level=none --/log/stderr/level=progress \"%1\"" }, { "fig2vect: Convert to EPS FULL (make)", "fig2vect.exe", "-ltex.full -a -m --/log/stdout/level=none --/log/stderr/level=progress \"%1\"" }, { "fig2vect: Convert to BB (make)", "fig2vect.exe", "-lbb -a -m --/log/stdout/level=none --/log/stderr/level=progress \"%1\"" }, { "fig2vect: Convert to SVG (make)", "fig2vect.exe", "-lsvg -a -m --/log/stdout/level=none --/log/stderr/level=progress \"%1\"" }, { NULL, NULL, NULL} }; /** Subdirectory bin. */ static char subdirectory[] = { "\\bin" }; /** Name of environment variable to change. */ static char str_path[] = { "PATH" }; /** String: Registry key name for environment variables. */ static char str_key[] = { "System\\CurrentControlSet\\Control\\Session Manager\\Environment" }; /** String: semicolon. */ static char str_semicolon[] = { ";" }; /** Get environment variable. @param b Result buffer. @param s Size of \a b in bytes. @param n Variable name. @return 1 on success, 0 on error. */ static int get_environment_variable(char *b, size_t s, char *n) { int back = 0; LONG result; HKEY base = HKEY_LOCAL_MACHINE; HKEY reskey; DWORD dwType, dwSz; result = RegCreateKeyExA( base, str_key, (DWORD)0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &reskey, NULL ); if(result == ERROR_SUCCESS) { dwType = REG_SZ; dwSz = s; result = RegQueryValueExA(reskey, n, NULL, &dwType, (BYTE *)b, &dwSz); if(result == ERROR_SUCCESS) { if((dwType == REG_SZ) || (REG_EXPAND_SZ)) { if(dwSz > 0) { b[(dwSz < s) ? dwSz : (s-1)] = '\0'; back = 1; } else { } } else { if(dwType == REG_EXPAND_SZ) { } } } else { } RegCloseKey(reskey); } else { } return back; } /** Set new value for environment variable. @param k Variable name. @param v New value. @return 1 on success, 0 on error. */ static int set_environment_variable(char *k, char *v) { int back = 0; char oldval[4096]; LONG result; HKEY base = HKEY_LOCAL_MACHINE; HKEY reskey; DWORD newDwType, dwType, dwSz; result = RegCreateKeyExA( base, str_key, (DWORD)0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &reskey, NULL ); if(result == ERROR_SUCCESS) { newDwType = REG_SZ; dwType = REG_SZ; dwSz = (DWORD)sizeof(oldval); result = RegQueryValueExA(reskey, k, NULL, &dwType, (BYTE *)oldval, &dwSz); if(result == ERROR_SUCCESS) { newDwType = dwType; } if((newDwType == REG_SZ) || (newDwType == REG_EXPAND_SZ)) { result = RegSetValueExA( reskey, k, (DWORD)0, newDwType, (BYTE *)v, (DWORD)(1+strlen(v)) ); if(result == ERROR_SUCCESS) { back = 1; } } RegCloseKey(reskey); } else { } return back; } /** Check whether a string contains a directory. @param fullpath Entire value of PATH @param dir Directory name to search for. @return 1 on success, 0 on error. */ static int path_contains(char *fullpath, char *dir) { int back = 0; char *p1, *p2; p1 = fullpath; while((p1) && (back == 0)) { p2 = strchr(p1, ';'); if(p2) { *p2 = '\0'; } if(stricmp(p1, dir) == 0) { back = 1; } if(p2) { *p2 = ';'; p2++; } p1 = p2; } return back; } /** Register directory in PATH environment variable. @param s Directory to register. */ static void register_directory_in_path_if_necessary(char *s) { char cpldir[4096]; /**< Complete directory name. */ char oldval[4096]; /**< Current PATH environment variable. */ char newval[4096]; /**< New PATH environment variable. */ if((strlen(s) + strlen(subdirectory)) < sizeof(cpldir)) { strcpy(cpldir, s); strcat(cpldir, subdirectory); if(get_environment_variable(oldval, sizeof(oldval), str_path)) { if(!path_contains(oldval, cpldir)) { if((strlen(cpldir) + strlen(oldval) + 2) < sizeof(newval)) { strcpy(newval, cpldir); strcat(newval, str_semicolon); strcat(newval, oldval); set_environment_variable(str_path, newval); } } } } } /** Unregister directory from PATH environment variable. @param s Directory to remove from PATH. */ static void unregister_directory_in_path_if_necessary(char *s) { char cpldir[4096]; /**< Complete directory name. */ char oldval[4096]; /**< Current PATH environment variable. */ char newval[4096]; /**< New PATH environment variable. */ int values_found; /**< Flag: this is not the first directory. */ char *p1; /**< Pointer to current directory. */ char *p2; /**< Pointer to next directory to process. */ if((strlen(s) + strlen(subdirectory)) < sizeof(cpldir)) { strcpy(cpldir, s); strcat(cpldir, subdirectory); if(get_environment_variable(oldval, sizeof(oldval), str_path)) { p1 = oldval; values_found = 0; newval[0] = '\0'; while(p1) { p2 = strchr(p1, ';'); if(p2) { *p2 = '\0'; } if(stricmp(p1, cpldir)) { if(values_found) { strcat(newval, str_semicolon); strcat(newval, p1); } else { strcpy(newval, p1); } values_found = 1; } if(p2) { *(p2++) = ';'; } p1 = p2; } set_environment_variable(str_path, newval); } } } /** Open a registry key. @param base Base key. @param n Name of subkey. @param reskey Pointer to HKEY to store the result. @return 1 on success, 0 on error. */ static int open_registry_key(HKEY base, char *n, HKEY *reskey) { int back = 0; LONG result; result = RegCreateKeyExA( base, n, (DWORD)0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, reskey, NULL ); if(result == ERROR_SUCCESS) { back = 1; } return back; } /** Set string registry entry. @param hk Key to create the entry. @param n The name of the entry. @param v Entry value. @return 1 on success, 0 on error. */ static int set_string_entry(HKEY hk, char *n, char *v) { int back = 0; long result; result = RegSetValueExA( hk, n, (DWORD)0, REG_SZ, (BYTE *)v, (DWORD)(1 + strlen(v)) ); if(result == ERROR_SUCCESS) { back = 1; } return back; } /** Retrieve string registry entry. @param hk The key to retrieve the entry from. @param n Name of the entry. @param b Buffer to store result. @param sz Result buffer size. @return 1 on success, 0 on error. */ static int get_string_entry(HKEY hk, char *n, char *b, size_t sz) { int back = 0; long result; DWORD dwSz, dwType; dwSz = sz; dwType = REG_SZ; result = RegQueryValueExA( hk, n, NULL, &dwType, (BYTE *)b, &dwSz ); if(result == ERROR_SUCCESS) { if(dwType == REG_SZ) { if(dwSz > 0) { b[(dwSz < sz) ? dwSz : (sz - 1)] = '\0'; back = 1; } } } else { } return back; } /** String backslash. */ static char str_bs[] = { "\\" }; /** String "shell". */ static char str_shell[] = { "shell" }; /** Command interpreter. */ static char str_command[] = { "command" }; /** bin subdirectory of installation directory. */ static char str_bin[] = { "bin" }; /** Remove a context menu entry. @param act Array listing all menu entries. @param ft File type to remove actions from. @param dn Directory where bmeps and tracecc reside. */ static void unregister_filetype_action(FileAction *act, char *ft, char *dn) { char keyname[LINESIZE]; size_t sz; FileAction *actptr; actptr = act; while((actptr->tt) || (actptr->cm) || (actptr->ar)) { if(actptr->tt) { sz = strlen(ft); sz += 2 * strlen(str_bs); sz += strlen(str_shell); sz += strlen(actptr->tt); if(sz < sizeof(keyname)) { sz += strlen(str_bs); sz += strlen(str_command); if(sz < sizeof(keyname)) { strcpy(keyname, ft); strcat(keyname, str_bs); strcat(keyname, str_shell); strcat(keyname, str_bs); strcat(keyname, actptr->tt); strcat(keyname, str_bs); strcat(keyname, str_command); RegDeleteKeyA(HKEY_CLASSES_ROOT, keyname); } else { } strcpy(keyname, ft); strcat(keyname, str_bs); strcat(keyname, str_shell); strcat(keyname, str_bs); strcat(keyname, actptr->tt); RegDeleteKeyA(HKEY_CLASSES_ROOT, keyname); } else { } } actptr++; } } /** Remove context menu entries for file name suffix. @param fns File name suffix. @param act List of context menu entries to remove. @param ft File type default. @param dn Directory name where bmeps and tracecc reside. */ static void unregister_action(char *fns, FileAction *act, char *ft, char *dn) { HKEY hk; char filetypebuffer[LINESIZE]; int have_filetype = 0; if(open_registry_key(HKEY_CLASSES_ROOT, fns, &hk)) { if(get_string_entry(hk, "", filetypebuffer, sizeof(filetypebuffer))) { have_filetype = 1; } else { if(strlen(ft) < sizeof(filetypebuffer)) { strcpy(filetypebuffer, ft); have_filetype = 1; } } RegCloseKey(hk); if(have_filetype) { if(open_registry_key(HKEY_CLASSES_ROOT, filetypebuffer, &hk)) { RegCloseKey(hk); unregister_filetype_action(act, filetypebuffer, dn); } } } else { /* ##### FAILED TO OPEN/CREATE KEY */ } unregister_filetype_action(act, ft, dn); } /** Register context menu entries for file type. @param act List of context menu entries. @param ft File type. @param dn Directory where tracecc and bmeps reside. */ static void register_filetype_action(FileAction *act, char *ft, char *dn) { HKEY hk; char keyname[LINESIZE]; char valuebuffer[LINESIZE]; FileAction *actptr; size_t sz; sz = strlen(ft); sz += strlen(str_bs); sz += strlen(str_shell); if(sz < sizeof(keyname)) { strcpy(keyname, ft); strcat(keyname, str_bs); strcat(keyname, str_shell); if(open_registry_key(HKEY_CLASSES_ROOT, keyname, &hk)) { RegCloseKey(hk); actptr = act; while((actptr->tt) || (actptr->cm) || (actptr->ar)) { if((actptr->tt) && (actptr->cm) && (actptr->ar)) { sz = strlen(ft); sz += strlen(str_bs); sz += strlen(str_shell); sz += strlen(str_bs); sz += strlen(actptr->tt); if(sz < sizeof(keyname)) { strcpy(keyname, ft); strcat(keyname, str_bs); strcat(keyname, str_shell); strcat(keyname, str_bs); strcat(keyname, actptr->tt); if(open_registry_key(HKEY_CLASSES_ROOT, keyname, &hk)) { RegCloseKey(hk); sz += strlen(str_bs); sz += strlen(str_command); if(sz < sizeof(keyname)) { strcat(keyname, str_bs); strcat(keyname, str_command); if(open_registry_key(HKEY_CLASSES_ROOT, keyname, &hk)) { sz = strlen(actptr->cm); sz += 2 * strlen(str_dq); if(dn) { sz += strlen(dn); sz += 2 * strlen(str_bs); sz += strlen(str_bin); } sz += strlen(actptr->ar); sz += 1; if(sz < sizeof(valuebuffer)) { strcpy(valuebuffer, str_dq); if(dn) { strcat(valuebuffer, dn); strcat(valuebuffer, str_bs); strcat(valuebuffer, str_bin); strcat(valuebuffer, str_bs); } strcat(valuebuffer, actptr->cm); strcat(valuebuffer, str_dq); strcat(valuebuffer, str_sp); strcat(valuebuffer, actptr->ar); set_string_entry(hk, "", valuebuffer); } RegCloseKey(hk); } } } } } actptr++; } } } } /** Register context menu entries for file name suffix. @param fns File name suffix. @param act List of context menu entries. @param ft Default file type name. @param dn Directory where bmeps and tracecc reside. */ static void register_action(char *fns, FileAction *act, char *ft, char *dn) { HKEY hk; char filetypebuffer[LINESIZE]; int have_filetype = 0; if(open_registry_key(HKEY_CLASSES_ROOT, fns, &hk)) { if(get_string_entry(hk, "", filetypebuffer, sizeof(filetypebuffer))) { have_filetype = 1; } else { if(strlen(ft) < sizeof(filetypebuffer)) { strcpy(filetypebuffer, ft); have_filetype = 1; } } RegCloseKey(hk); if(have_filetype) { if(open_registry_key(HKEY_CLASSES_ROOT, filetypebuffer, &hk)) { RegCloseKey(hk); register_filetype_action(act, filetypebuffer, dn); } } } else { /* ##### FAILED TO OPEN/CREATE KEY */ } } /** Create context menu entries for bitmap files to invoke bmeps. @param dirname Installation directory name. */ void BmepsContextMenuEntries(char *dirname) { register_action(".png", bmeps_actions, "pngfile", dirname); register_action(".jpg", bmeps_actions, "jpegfile", dirname); register_action(".jpeg", bmeps_actions, "jpegfile", dirname); register_action(".pgm", bmeps_actions, "netpbmfile", dirname); register_action(".pbm", bmeps_actions, "netpbmfile", dirname); register_action(".ppm", bmeps_actions, "netpbmfile", dirname); register_action(".pnm", bmeps_actions, "netpbmfile", dirname); register_action(".tif", bmeps_actions, "tifffile", dirname); register_action(".tiff", bmeps_actions, "tifffile", dirname); register_action(".tif", bmeps_fax_actions, "tifffile", dirname); register_action(".tiff", bmeps_fax_actions, "tifffile", dirname); } /** Create context menu entries for directories to invoke bmeps. @param dirname Installation directory name. */ void BmepsDirectoryContextMenuEntries(char *dirname) { register_filetype_action(bmeps_dir_actions, "Directory", NULL); } /** Create context menu entries for directories to invoke tracecc. @param dirname Installation directory name. */ void TraceccDirectoryContextMenuEntries(char *dirname) { register_filetype_action(tracecc_actions, "Directory", NULL); } /** Create context menu entries for Fig files. @param dirname Installation directory name. */ void FigContextMenuEntries(char *dirname) { register_action(".fig", fig2vect_actions, "figfile", dirname); } /** Add context menu entries for Fig files. @param dirname Installation directory name. */ void FigDirectoryContextMenuEntries(char *dirname) { #if 0 register_filetype_action(fig2vect_directory_actions, "Directory", dirname); #endif } /** Create context menu enries. @param dirname Installation directory name. */ static void register_actions(char *dirname) { if(install_cmd & CMD_BMEPS_FILE) { BmepsContextMenuEntries(dirname); } if(install_cmd & CMD_BMEPS_DIR) { BmepsDirectoryContextMenuEntries(dirname); } if(install_cmd & CMD_TRACECC_DIR) { TraceccDirectoryContextMenuEntries(dirname); } if(install_cmd & CMD_FIG2VECT_FILE) { FigContextMenuEntries(dirname); } if(install_cmd & CMD_FIG2VECT_DIR) { FigDirectoryContextMenuEntries(dirname); } } /** Remove all context menu entries. @param dirname Installation directory name. */ void RemoveContextMenuEntries(char *dirname) { unregister_action(".png", bmeps_actions, "pngfile", dirname); unregister_action(".jpg", bmeps_actions, "jpegfile", dirname); unregister_action(".jpeg", bmeps_actions, "jpegfile", dirname); unregister_action(".pgm", bmeps_actions, "netpbmfile", dirname); unregister_action(".pbm", bmeps_actions, "netpbmfile", dirname); unregister_action(".ppm", bmeps_actions, "netpbmfile", dirname); unregister_action(".pnm", bmeps_actions, "netpbmfile", dirname); unregister_action(".tif", bmeps_actions, "tifffile", dirname); unregister_action(".tiff", bmeps_actions, "tifffile", dirname); unregister_action(".tif", bmeps_fax_actions, "tifffile", dirname); unregister_action(".tiff", bmeps_fax_actions, "tifffile", dirname); unregister_action(".fig", fig2vect_actions, "figfile", dirname); unregister_filetype_action(bmeps_dir_actions, "Directory", NULL); unregister_filetype_action(tracecc_actions, "Directory", NULL); unregister_filetype_action(fig2vect_directory_actions, "Directory", dirname); } /** Question, whether to install or uninstall. */ static char *q1[] = { "Do you wish to install or uninstall context menu entries?", "1 Install", "2 Uninstall", "q Quit", NULL }; /** Decide for install or uninstall. @return 0=install, 1=uninstall, -1=no action. */ static int install_or_uninstall(void) { char buffer[1024]; int back = 0, value = 0; char **ptr; ptr = q1; while(*ptr) { printf("%s\n", *(ptr++)); } if(fgets(buffer, sizeof(buffer), stdin)) { if(sscanf(buffer, "%d", &value) == 1) { switch(value) { case 1: back = 0; break; case 2: back = 1; break; default: back = -1; break; } } else { back = -1; } } else { back = -1; } return back; } /** Questions for install command modification. */ static char *q2[] = { "Add bmeps context menu entries to bitmap files? (Y/n): ", "Add fig2vect context menu entries to *.fig files? (Y/n): ", "Add tracecc context menu entries to directories? (Y/n): ", "Add bmeps context menu entries to directories (Y/N): ", "Add fig2vect context menu entries to directories? (y/N): ", NULL }; /** Modify the install command. @param i Index of question text in \a q2. @param v Value to add or remove. @param d Default answer. @return Modified installation command. */ static int mod_install_cmd(int i, int v, int d) { char buffer[256], *p1; int back = 0; int m = d; printf("%s", q2[i]); if(fgets(buffer, sizeof(buffer), stdin)) { p1 = dkstr_start(buffer, NULL); if(p1) { dkstr_chomp(p1, NULL); if(dkstr_is_bool(p1)) { back = (dkstr_is_on(p1) ? v : 0); } } } if(m) { back = v; } return back; } /** Set up buffers. @param dn Directory name (installation directory). */ static void setup_buffers(char *dn) { size_t sz; if(dn) { sz = strlen(part1) + strlen(dn) + strlen(part2) + strlen(fn1) + strlen(str_sp) + 3; if(sz < sizeof(buffer1)) { strcpy(buffer1, part1); strcat(buffer1, str_dq); strcat(buffer1, dn); strcat(buffer1, part2); strcat(buffer1, str_dq); strcat(buffer1, str_sp); strcat(buffer1, fn1); bmeps_dir_actions[0].ar = buffer1; } sz = strlen(part1) + strlen(dn) + strlen(part3) + strlen(fn1) + strlen(str_sp) + 3; if(sz < sizeof(buffer2)) { strcpy(buffer2, part1); strcat(buffer2, str_dq); strcat(buffer2, dn); strcat(buffer2, part3); strcat(buffer2, str_dq); strcat(buffer2, str_sp); strcat(buffer2, fn1); tracecc_actions[0].ar = buffer2; } } } /** Modify PATH environmetn variable to remove dktools. */ static void modify_path_to_remove_dklibs(void) { int have_directory = 0; /**< Flag: Have directory name to remove. */ char dirname[4096]; /**< Base directory to remove from PATH. */ HKEY reskey; /**< Registry key. */ LONG result; /**< Registry operation result. */ DWORD dwType; /**< Registry entry type. */ DWORD dwSz; /**< Registry entry value buffer size. */ result = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\\DkApp", (DWORD)0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &reskey, NULL ); if(result == ERROR_SUCCESS) { dwType = REG_SZ; dwSz = sizeof(dirname); result = RegQueryValueExA( reskey, "DIRECTORY", NULL, &dwType, (BYTE *)dirname, &dwSz ); if(result == ERROR_SUCCESS) { if(dwType == REG_SZ) { if(dwSz > 0) { dirname[(dwSz < sizeof(dirname)) ? dwSz : (sizeof(dirname) - 1)]='\0'; have_directory = 1; dksf_correct_fnsep(dirname); } } } RegCloseKey(reskey); } if(have_directory) { unregister_directory_in_path_if_necessary(dirname); } } #if !DKWFTREG_DLL /** The main() function in the dkwftreg program. @param argc number of command line arguments. @param argv Command line arguments array. @return 0 on success, 1 on errors. */ int main(int argc, char *argv[]) { char dirbuffer[1024]; char *dynbuffer = NULL; int cmd = 0; int i; char *directoryname = NULL; #line 1131 "dkwftreg.ctr" if(argc > 1) { if(strcmp(argv[1], "-u") == 0) { cmd = 1; } else { { size_t sz; sz = 0; for(i = 1; i < argc; i++) { sz += strlen(argv[i]); sz++; } dynbuffer = malloc(sz); if(dynbuffer) { for(i = 1; i < argc; i++) { if(i == 1) { strcpy(dynbuffer, argv[i]); } else { strcat(dynbuffer, str_sp); strcat(dynbuffer, argv[i]); } } directoryname = dynbuffer; } else { directoryname = argv[1]; fprintf(stderr, "ERROR: Not enough memory!\n"); fflush(stderr); } } } } else { install_cmd = 0; cmd = install_or_uninstall(); if(cmd == 0) { printf("Dirk Krause's Tools base directory [%s]: ", default_base_dir); if(fgets(dirbuffer, sizeof(dirbuffer), stdin)) { directoryname = dkstr_start(dirbuffer, NULL); if(!(directoryname)) { directoryname = default_base_dir; } else { dkstr_chomp(directoryname, NULL); } } else { directoryname = default_base_dir; } install_cmd |= mod_install_cmd(0, CMD_BMEPS_FILE, 1); install_cmd |= mod_install_cmd(1, CMD_FIG2VECT_FILE, 1); install_cmd |= mod_install_cmd(2, CMD_TRACECC_DIR, 1); install_cmd |= mod_install_cmd(3, CMD_BMEPS_DIR, 1); install_cmd |= mod_install_cmd(4, CMD_FIG2VECT_DIR, 0); } } setup_buffers(directoryname); switch(cmd) { case -1: {} break; case 1: { RemoveContextMenuEntries(directoryname); modify_path_to_remove_dklibs(); } break; default: { register_actions(directoryname); register_directory_in_path_if_necessary(directoryname); } break; } if(dynbuffer) { free(dynbuffer); } #line 1199 "dkwftreg.ctr" exit(exval); return exval; } #endif