Changeset 8421 for trunk/src/setupapi/setupx_main.c
- Timestamp:
- May 15, 2002, 2:39:57 PM (23 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/setupapi/setupx_main.c
r6712 r8421 3 3 * 4 4 * Copyright 1998,2000 Andreas Mohr 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 5 19 * 6 20 * FIXME: Rather non-functional functions for now. … … 30 44 * Ip .INF parsing (infparse.c) 31 45 * LDD logical device descriptor (ldd.c ?) 32 * LDID logical device ID 46 * LDID logical device ID 33 47 * SU setup (setup.c ?) 34 48 * Tp text processing (textproc.c ?) … … 44 58 #include <stdlib.h> 45 59 #include <stdio.h> 60 #include <string.h> 46 61 #include "winreg.h" 62 #include "winerror.h" 47 63 #include "wine/winuser16.h" 64 #include "setupapi.h" 48 65 #include "setupx16.h" 49 #include "setup x_private.h"66 #include "setupapi_private.h" 50 67 #include "winerror.h" 51 #include "heap.h" 52 #include "debugtools.h" 53 54 DEFAULT_DEBUG_CHANNEL(setupx); 55 56 /*********************************************************************** 57 * SURegOpenKey 68 #include "wine/debug.h" 69 70 WINE_DEFAULT_DEBUG_CHANNEL(setupapi); 71 72 /*********************************************************************** 73 * SURegOpenKey (SETUPX.47) 58 74 */ 59 75 DWORD WINAPI SURegOpenKey( HKEY hkey, LPCSTR lpszSubKey, LPHKEY retkey ) … … 64 80 65 81 /*********************************************************************** 66 * SURegQueryValueEx 82 * SURegQueryValueEx (SETUPX.50) 67 83 */ 68 84 DWORD WINAPI SURegQueryValueEx( HKEY hkey, LPSTR lpszValueName, … … 123 139 p = q+1; 124 140 } 125 141 126 142 /* put number of entries at beginning of list */ 127 143 *(DWORD *)res = count; … … 141 157 } 142 158 143 static void SETUPX_IsolateSubString(LPSTR *begin, LPSTR *end) 144 { 145 LPSTR p, q; 146 147 p = *begin; 148 q = *end; 149 150 while ((p < q) && ((*p == ' ') || (*p == '\t'))) p++; 151 while ((p < q) && (*p == '"')) p++; 152 153 while ((q-1 >= p) && ((*(q-1) == ' ') || (*(q-1) == '\t'))) q--; 154 while ((q-1 >= p) && (*(q-1) == '"')) q--; 155 156 *begin = p; 157 *end = q; 158 } 159 160 /* 161 * Example: HKLM,"Software\Microsoft\Windows\CurrentVersion","ProgramFilesDir",,"C:\" 162 * FIXME: use SETUPX_GetSubStrings() instead. 163 * Hmm, but on the other hand SETUPX_GetSubStrings() will probably 164 * soon be replaced by InitSubstrData() etc. anyway. 165 * 166 */ 167 static BOOL SETUPX_LookupRegistryString(LPSTR regstr, LPSTR buffer, DWORD buflen) 168 { 169 HANDLE heap = GetProcessHeap(); 170 LPSTR items[5]; 171 LPSTR p, q, next; 172 int len, n; 173 HKEY hkey, hsubkey; 174 DWORD dwType; 175 176 TRACE("retrieving '%s'\n", regstr); 177 178 p = regstr; 179 180 /* isolate root key, subkey, value, flag, defval */ 181 for (n=0; n < 5; n++) 182 { 183 q = strchr(p, ','); 184 if (!q) 185 { 186 if (n == 4) 187 q = p+strlen(p); 188 else 189 return FALSE; 190 } 191 next = q+1; 192 if (q < regstr) 193 return FALSE; 194 SETUPX_IsolateSubString(&p, &q); 195 len = (int)q - (int)p; 196 items[n] = HeapAlloc(heap, 0, len+1); 197 strncpy(items[n], p, len); 198 items[n][len] = '\0'; 199 p = next; 200 } 201 TRACE("got '%s','%s','%s','%s','%s'\n", 202 items[0], items[1], items[2], items[3], items[4]); 203 204 /* check root key */ 205 if (!strcasecmp(items[0], "HKCR")) 206 hkey = HKEY_CLASSES_ROOT; 207 else 208 if (!strcasecmp(items[0], "HKCU")) 209 hkey = HKEY_CURRENT_USER; 210 else 211 if (!strcasecmp(items[0], "HKLM")) 212 hkey = HKEY_LOCAL_MACHINE; 213 else 214 if (!strcasecmp(items[0], "HKU")) 215 hkey = HKEY_USERS; 216 else 217 { /* HKR ? -> relative to key passed to GenInstallEx */ 218 FIXME("unsupported regkey '%s'\n", items[0]); 219 goto regfailed; 220 } 221 222 if (RegOpenKeyA(hkey, items[1], &hsubkey) != ERROR_SUCCESS) 223 goto regfailed; 224 225 if (RegQueryValueExA(hsubkey, items[2], NULL, &dwType, buffer, &buflen) 226 != ERROR_SUCCESS) 227 goto regfailed; 228 goto done; 229 230 regfailed: 231 if (buffer) strcpy(buffer, items[4]); /* I don't care about buflen */ 232 done: 233 for (n=0; n < 5; n++) 234 HeapFree(heap, 0, items[n]); 235 if (buffer) 236 TRACE("return '%s'\n", buffer); 237 return TRUE; 238 } 239 240 static LPSTR SETUPX_GetSections(LPCSTR filename) 241 { 242 LPSTR buf = NULL; 243 DWORD len = 1024, res; 244 245 do { 246 buf = HeapReAlloc(GetProcessHeap(), 0, buf, len); 247 res = GetPrivateProfileStringA(NULL, NULL, NULL, buf, len, filename); 248 len *= 2; 249 } while ((!res) && (len < 1048576)); 250 if (!res) 251 { 252 HeapFree(GetProcessHeap(), 0, buf); 253 return NULL; 254 } 255 return buf; 256 } 257 258 static LPSTR SETUPX_GetSectionEntries(LPCSTR filename, LPCSTR section) 259 { 260 LPSTR buf = NULL; 261 DWORD len = 1024, res; 262 263 do { 264 buf = HeapReAlloc(GetProcessHeap(), 0, buf, len); 265 res = GetPrivateProfileSectionA(section, buf, len, filename); 266 len *= 2; 267 } while ((!res) && (len < 1048576)); 268 if (!res) 269 { 270 HeapFree(GetProcessHeap(), 0, buf); 271 return NULL; 272 } 273 return buf; 274 } 275 276 277 /*********************************************************************** 278 * InstallHinfSection 159 160 /*********************************************************************** 161 * InstallHinfSection (SETUPX.527) 279 162 * 280 163 * hwnd = parent window … … 283 166 * Here "DefaultInstall" is the .inf file section to be installed (optional). 284 167 * The 132 value is made of the HOW_xxx flags and sometimes 128 (-> setupx16.h). 285 * 168 * 286 169 * nCmdShow = nCmdShow of CreateProcess 287 170 */ 288 typedef INT WINAPI (*MSGBOX_PROC)( HWND, LPCSTR, LPCSTR, UINT );289 171 RETERR16 WINAPI InstallHinfSection16( HWND16 hwnd, HINSTANCE16 hinst, LPCSTR lpszCmdLine, INT16 nCmdShow) 290 172 { … … 292 174 DWORD count; 293 175 HINF16 hInf = 0; 294 RETERR16 res = OK ;176 RETERR16 res = OK, tmp; 295 177 WORD wFlags; 296 178 BOOL reboot = FALSE; 297 HMODULE hMod; 298 MSGBOX_PROC pMessageBoxA; 299 179 300 180 TRACE("(%04x, %04x, %s, %d);\n", hwnd, hinst, lpszCmdLine, nCmdShow); 301 181 302 182 pSub = SETUPX_GetSubStrings((LPSTR)lpszCmdLine, ' '); 303 183 … … 310 190 goto end; 311 191 } 192 if (VcpOpen16(NULL, 0)) 193 goto end; 312 194 if (GenInstall16(hInf, *(pSub+count-2), GENINSTALL_DO_ALL) != OK) 313 195 goto end; … … 321 203 case HOW_ALWAYS_PROMPT_REBOOT: 322 204 case HOW_PROMPT_REBOOT: 323 if ((hMod = GetModuleHandleA("user32.dll"))) 324 { 325 if ((pMessageBoxA = (MSGBOX_PROC)GetProcAddress( hMod, "MessageBoxA" ))) 326 { 327 328 if (pMessageBoxA(hwnd, "You must restart Wine before the new settings will take effect.\n\nDo you want to exit Wine now ?", "Systems Settings Change", MB_YESNO|MB_ICONQUESTION) == IDYES) 329 reboot = TRUE; 330 } 331 } 205 if (MessageBoxA(hwnd, "You must restart Wine before the new settings will take effect.\n\nDo you want to exit Wine now ?", "Systems Settings Change", MB_YESNO|MB_ICONQUESTION) == IDYES) 206 reboot = TRUE; 332 207 break; 333 208 default: … … 335 210 goto end; 336 211 } 337 212 338 213 res = OK; 339 214 end: 340 IpClose16(hInf); 215 tmp = VcpClose16(VCPFL_ALL, NULL); 216 if (tmp != OK) 217 res = tmp; 218 tmp = IpClose16(hInf); 219 if (tmp != OK) 220 res = tmp; 341 221 SETUPX_FreeSubStrings(pSub); 342 222 if (reboot) … … 497 377 }; 498 378 499 /* 379 /* 500 380 * LDD == Logical Device Descriptor 501 381 * LDID == Logical Device ID 502 382 * 503 383 * The whole LDD/LDID business might go into a separate file named 504 * ldd.c or logdevice.c.384 * ldd.c. 505 385 * At the moment I don't know what the hell these functions are really doing. 506 386 * That's why I added reporting stubs. … … 575 455 if (hKey) RegCloseKey(hKey); 576 456 } 577 457 578 458 /*********************************************************************** 579 459 * CtlDelLdd (SETUPX.37) … … 613 493 pFirstLDD = NULL; 614 494 HeapFree(GetProcessHeap(), 0, pCurr); 615 495 616 496 return OK; 617 497 } … … 634 514 * ERR_VCP_LDDINVALID if pldd->cbSize != structsize 635 515 * 1 in all other cases ?? 636 * 516 * 637 517 */ 638 518 RETERR16 WINAPI CtlFindLdd16(LPLOGDISKDESC pldd) … … 641 521 642 522 TRACE("(%p)\n", pldd); 643 523 644 524 if (!std_LDDs_done) 645 525 SETUPX_CreateStandardLDDs(); … … 661 541 memcpy(pldd, pCurr->pldd, pldd->cbSize); 662 542 /* hmm, we probably ought to strcpy() the string ptrs here */ 663 543 664 544 return 1; /* what is this ?? */ 665 545 } … … 697 577 pCurr = pCurr->next; 698 578 } 699 if ( pCurr == NULL) /* hit end of list */579 if (!pCurr || pldd->ldid != pCurr->pldd->ldid) 700 580 { 701 581 is_new = TRUE; … … 716 596 717 597 if (pldd->pszPath) 718 pCurrLDD->pszPath = HEAP_strdupA(heap, 0, pldd->pszPath); 598 { 599 pCurrLDD->pszPath = HeapAlloc( heap, 0, strlen(pldd->pszPath)+1 ); 600 strcpy( pCurrLDD->pszPath, pldd->pszPath ); 601 } 719 602 if (pldd->pszVolLabel) 720 pCurrLDD->pszVolLabel = HEAP_strdupA(heap, 0, pldd->pszVolLabel); 603 { 604 pCurrLDD->pszVolLabel = HeapAlloc( heap, 0, strlen(pldd->pszVolLabel)+1 ); 605 strcpy( pCurrLDD->pszVolLabel, pldd->pszVolLabel ); 606 } 721 607 if (pldd->pszDiskName) 722 pCurrLDD->pszDiskName = HEAP_strdupA(heap, 0, pldd->pszDiskName); 608 { 609 pCurrLDD->pszDiskName = HeapAlloc( heap, 0, strlen(pldd->pszDiskName)+1 ); 610 strcpy( pCurrLDD->pszDiskName, pldd->pszDiskName ); 611 } 723 612 724 613 if (is_new) /* link into list */ … … 732 621 pFirstLDD = pCurr; 733 622 } 734 623 735 624 return OK; 736 625 } … … 758 647 * RETURN 759 648 * ERR_VCP_LDDINVALID if pldd->cbSize != structsize 760 * 649 * 761 650 */ 762 651 static RETERR16 SETUPX_GetLdd(LPLOGDISKDESC pldd) … … 830 719 LOGDISKDESC_S ldd; 831 720 TRACE("(%d, '%s');\n", ldid, szPath); 832 721 722 SetupSetDirectoryIdA( 0, ldid, szPath ); 833 723 INIT_LDD(ldd, ldid); 834 724 ldd.pszPath = szPath; 835 725 return CtlSetLdd16(&ldd); 836 726 } 837 838 /*839 * Find the value of a custom LDID in a .inf file840 * e.g. for 49301:841 * 49300,49301=ProgramFilesDir,5842 * -- profile section lookup -->843 * [ProgramFilesDir]844 * HKLM,"Software\Microsoft\Windows\CurrentVersion","ProgramFilesDir",,"%24%"845 * -- GenFormStrWithoutPlaceHolders16 -->846 * HKLM,"Software\Microsoft\Windows\CurrentVersion","ProgramFilesDir",,"C:\"847 * -- registry lookup -->848 * C:\Program Files (or C:\ if not found in registry)849 *850 * FIXME:851 * - maybe we ought to add a caching array for speed ? - I don't care :)852 * - not sure whether the processing is correct - sometimes there are equal853 * LDIDs for both install and removal sections.854 * - probably the whole function can be removed as installers add that on their855 * own856 */857 static BOOL SETUPX_AddCustomLDID(int ldid, INT16 hInf)858 {859 char ldidstr[6];860 LPSTR sectionbuf = NULL, entrybuf = NULL, regsectionbuf = NULL;861 LPCSTR filename;862 LPSTR pSec, pEnt, pEqual, p, *pSub = NULL;863 BOOL ret = FALSE;864 char buffer[MAX_PATH];865 LOGDISKDESC_S ldd;866 867 sprintf(ldidstr, "%d", ldid);868 filename = IP_GetFileName(hInf);869 if (!(sectionbuf = SETUPX_GetSections(filename)))870 {871 ERR("couldn't get sections !\n");872 return FALSE;873 }874 for (pSec=sectionbuf; *pSec; pSec += strlen(pSec)+1)875 {876 if (!(entrybuf = SETUPX_GetSectionEntries(filename, pSec)))877 {878 ERR("couldn't get section entries !\n");879 goto end;880 }881 for (pEnt=entrybuf; *pEnt; pEnt += strlen(pEnt)+1)882 {883 if (strstr(pEnt, ldidstr))884 {885 pEqual = strchr(pEnt, '=');886 if (!pEqual) /* crippled entry ?? */887 continue;888 889 /* make sure we found the LDID on left side of the equation */890 if (pEnt+strlen(ldidstr) <= pEqual)891 { /* found */892 893 /* but we don't want entries in the strings section */894 if (!strcasecmp(pSec, "Strings"))895 goto next_section;896 p = pEqual+1;897 goto found;898 }899 }900 }901 next_section:902 }903 goto end;904 found:905 TRACE("found entry '%s'\n", p);906 pSub = SETUPX_GetSubStrings(p, ',');907 if (*(DWORD *)pSub > 2)908 {909 ERR("malformed entry '%s' ?\n", p);910 goto end;911 }912 TRACE("found section '%s'\n", *(pSub+1));913 /* FIXME: what are the optional flags at the end of an entry used for ?? */914 915 /* get the location of the registry key from that section */916 if (!(regsectionbuf = SETUPX_GetSectionEntries(filename, *(pSub+1))))917 {918 ERR("couldn't get registry section entries !\n");919 goto end;920 }921 /* sectionbuf is > 1024 bytes anyway, so use it */922 GenFormStrWithoutPlaceHolders16(sectionbuf, regsectionbuf, hInf);923 ret = SETUPX_LookupRegistryString(sectionbuf, buffer, MAX_PATH);924 TRACE("return '%s'\n", buffer);925 INIT_LDD(ldd, ldid);926 ldd.pszPath = buffer;927 CtlSetLdd16(&ldd);928 end:929 SETUPX_FreeSubStrings(pSub);930 if (sectionbuf) HeapFree(GetProcessHeap(), 0, sectionbuf);931 if (entrybuf) HeapFree(GetProcessHeap(), 0, entrybuf);932 if (regsectionbuf) HeapFree(GetProcessHeap(), 0, regsectionbuf);933 return ret;934 }935 936 /*937 * Translate a logical disk identifier (LDID) into its string representation938 * I'm afraid this can be totally replaced by CtlGetLddPath().939 */940 static BOOL SETUPX_IP_TranslateLDID(int ldid, LPSTR *p, HINF16 hInf)941 {942 BOOL handled = FALSE;943 LOGDISKDESC_S ldd;944 945 ldd.cbSize = sizeof(LOGDISKDESC_S);946 ldd.ldid = ldid;947 if (CtlFindLdd16(&ldd) == ERR_VCP_LDDFIND)948 {949 /* hmm, it seems the installers already do the work for us950 * (by calling CtlSetLddPath) that SETUPX_AddCustomLDID951 * is supposed to do. Grmbl ;-)952 * Well, I'll leave it here anyway, but print error... */953 ERR("hmm, LDID %d not registered yet !?\n", ldid);954 handled = SETUPX_AddCustomLDID(ldid, hInf);955 }956 else957 handled = TRUE;958 959 SETUPX_GetLdd(&ldd);960 961 if (!handled)962 {963 FIXME("What is LDID %d ??\n", ldid);964 *p = "LDID_FIXME";965 }966 else967 *p = ldd.pszPath;968 969 return handled;970 }971 972 /***********************************************************************973 * GenFormStrWithoutPlaceHolders974 *975 * ought to be pretty much implemented, I guess...976 */977 void WINAPI GenFormStrWithoutPlaceHolders16( LPSTR szDst, LPCSTR szSrc, HINF16 hInf)978 {979 LPCSTR pSrc = szSrc, pSrcEnd = szSrc + strlen(szSrc);980 LPSTR pDst = szDst, p, pPHBegin;981 int count;982 983 TRACE("(%p, '%s', %04x);\n", szDst, szSrc, hInf);984 while (pSrc < pSrcEnd)985 {986 p = strchr(pSrc, '%');987 if (p)988 {989 count = (int)p - (int)pSrc;990 strncpy(pDst, pSrc, count);991 pSrc += count;992 pDst += count;993 pPHBegin = p+1;994 p = strchr(pPHBegin, '%');995 if (p)996 {997 char placeholder[80]; /* that really ought to be enough ;) */998 int ldid;999 BOOL done = TRUE;1000 count = (int)p - (int)pPHBegin;1001 strncpy(placeholder, pPHBegin, count);1002 placeholder[count] = '\0';1003 ldid = atoi(placeholder);1004 if (ldid)1005 {1006 LPSTR p;1007 done = SETUPX_IP_TranslateLDID(ldid, &p, hInf);1008 strcpy(pDst, p);1009 if (done)1010 pDst += strlen(pDst);1011 }1012 else1013 { /* hmm, string placeholder. Need to look up1014 in the [strings] section of the hInf */1015 DWORD ret;1016 char buf[256]; /* long enough ? */1017 1018 ret = GetPrivateProfileStringA("strings", placeholder, "",1019 buf, 256, IP_GetFileName(hInf));1020 if (ret)1021 {1022 strcpy(pDst, buf);1023 pDst += strlen(buf);1024 }1025 else1026 {1027 ERR("placeholder string '%s' not found !\n", placeholder);1028 done = FALSE;1029 }1030 }1031 if (!done)1032 { /* copy raw placeholder string over */1033 count = (int)p - (int)pPHBegin + 2;1034 strncpy(pDst, pPHBegin-1, count);1035 pDst += count;1036 1037 }1038 pSrc = p+1;1039 continue;1040 }1041 }1042 1043 /* copy the remaining source string over */1044 strncpy(pDst, pSrc, (int)pSrcEnd - (int)pSrc + 1);1045 break;1046 }1047 TRACE("ret '%s'\n", szDst);1048 }1049 1050 /***********************************************************************1051 * VcpOpen1052 *1053 * No idea what to do here.1054 */1055 RETERR16 WINAPI VcpOpen16(VIFPROC vifproc, LPARAM lparamMsgRef)1056 {1057 FIXME("(%p, %08lx), stub.\n", vifproc, lparamMsgRef);1058 return OK;1059 }1060 1061 /***********************************************************************1062 * VcpClose1063 *1064 * Is fl related to VCPDISKINFO.fl ?1065 */1066 RETERR16 WINAPI VcpClose16(WORD fl, LPCSTR lpszBackupDest)1067 {1068 FIXME("(%04x, '%s'), stub.\n", fl, lpszBackupDest);1069 return OK;1070 }1071 1072 /*1073 * Copy all items in a CopyFiles entry over to the destination1074 *1075 * - VNLP_xxx is what is given as flags for a .INF CopyFiles section1076 */1077 static BOOL SETUPX_CopyFiles(LPSTR *pSub, HINF16 hInf)1078 {1079 BOOL res = FALSE;1080 unsigned int n;1081 LPCSTR filename = IP_GetFileName(hInf);1082 LPSTR pCopyEntry;1083 char pDestStr[MAX_PATH];1084 LPSTR pSrcDir, pDstDir;1085 LPSTR pFileEntries, p;1086 WORD ldid;1087 LOGDISKDESC_S ldd;1088 LPSTR *pSubFile;1089 LPSTR pSrcFile, pDstFile;1090 1091 for (n=0; n < *(DWORD *)pSub; n++)1092 {1093 pCopyEntry = *(pSub+1+n);1094 if (*pCopyEntry == '@')1095 {1096 ERR("single file not handled yet !\n");1097 continue;1098 }1099 1100 /* get source directory for that entry */1101 INIT_LDD(ldd, LDID_SRCPATH);1102 SETUPX_GetLdd(&ldd);1103 pSrcDir = ldd.pszPath;1104 1105 /* get destination directory for that entry */1106 if (!(GetPrivateProfileStringA("DestinationDirs", pCopyEntry, "",1107 pDestStr, sizeof(pDestStr), filename)))1108 continue;1109 1110 /* translate destination dir if given as LDID */1111 ldid = atoi(pDestStr);1112 if (ldid)1113 {1114 if (!(SETUPX_IP_TranslateLDID(ldid, &pDstDir, hInf)))1115 continue;1116 }1117 else1118 pDstDir = pDestStr;1119 1120 /* now that we have the destination dir, iterate over files to copy */1121 pFileEntries = SETUPX_GetSectionEntries(filename, pCopyEntry);1122 for (p=pFileEntries; *p; p +=strlen(p)+1)1123 {1124 pSubFile = SETUPX_GetSubStrings(p, ',');1125 pSrcFile = *(pSubFile+1);1126 pDstFile = (*(DWORD *)pSubFile > 1) ? *(pSubFile+2) : pSrcFile;1127 TRACE("copying file '%s\\%s' to '%s\\%s'\n", pSrcDir, pSrcFile, pDstDir, pDstFile);1128 if (*(DWORD *)pSubFile > 2)1129 {1130 WORD flag;1131 if ((flag = atoi(*(pSubFile+3)))) /* ah, flag */1132 {1133 if (flag & 0x2c)1134 FIXME("VNLP_xxx flag %d not handled yet.\n", flag);1135 }1136 else1137 FIXME("temp file name '%s' given. Need to register in wininit.ini !\n", *(pSubFile+3)); /* strong guess that this is VcpQueueCopy() */1138 }1139 SETUPX_FreeSubStrings(pSubFile);1140 /* we don't copy ANYTHING yet ! (I'm too lazy and want to verify1141 * this first before destroying whole partitions ;-) */1142 }1143 }1144 1145 return res;1146 }1147 1148 /***********************************************************************1149 * GenInstall1150 *1151 * general install function for .INF file sections1152 *1153 * This is not perfect - patch whenever you can !1154 *1155 * wFlags == GENINSTALL_DO_xxx1156 * e.g. NetMeeting:1157 * first call GENINSTALL_DO_REGSRCPATH | GENINSTALL_DO_FILES,1158 * second call GENINSTALL_DO_LOGCONFIG | CFGAUTO | INI2REG | REG | INI1159 */1160 RETERR16 WINAPI GenInstall16(HINF16 hInfFile, LPCSTR szInstallSection, WORD wFlags)1161 {1162 LPCSTR filename = IP_GetFileName(hInfFile);1163 LPSTR pEntries, p, pEnd;1164 DWORD len;1165 LPSTR *pSub;1166 1167 FIXME("(%04x, '%s', %04x), semi-stub. Please implement additional operations here !\n", hInfFile, szInstallSection, wFlags);1168 pEntries = SETUPX_GetSectionEntries(filename, szInstallSection);1169 if (!pEntries)1170 {1171 ERR("couldn't find entries for section '%s' !\n", szInstallSection);1172 return ERR_IP_SECT_NOT_FOUND;1173 }1174 for (p=pEntries; *p; p +=strlen(p)+1)1175 {1176 pEnd = strchr(p, '=');1177 if (!pEnd) continue;1178 pSub = SETUPX_GetSubStrings(pEnd+1, ','); /* split entries after the '=' */1179 SETUPX_IsolateSubString(&p, &pEnd);1180 len = (int)pEnd - (int)p;1181 1182 if (wFlags & GENINSTALL_DO_FILES)1183 {1184 if (!strncasecmp(p, "CopyFiles", len))1185 {1186 SETUPX_CopyFiles(pSub, hInfFile);1187 continue;1188 }1189 #if IMPLEMENT_THAT1190 else1191 if (!strncasecmp(p, "DelFiles", len))1192 {1193 SETUPX_DelFiles(filename, szInstallSection, pSub);1194 continue;1195 }1196 #endif1197 }1198 if (wFlags & GENINSTALL_DO_INI)1199 {1200 #if IMPLEMENT_THAT1201 if (!strncasecmp(p, "UpdateInis", len))1202 {1203 SETUPX_UpdateInis(filename, szInstallSection, pSub);1204 continue;1205 }1206 #endif1207 }1208 if (wFlags & GENINSTALL_DO_REG)1209 {1210 #if IMPLEMENT_THAT1211 /* probably use SUReg*() functions here */1212 if (!strncasecmp(p, "AddReg", len))1213 {1214 SETUPX_AddReg(filename, szInstallSection, pSub);1215 continue;1216 }1217 else1218 if (!strncasecmp(p, "DelReg", len))1219 {1220 SETUPX_DelReg(filename, szInstallSection, pSub);1221 continue;1222 }1223 #endif1224 }1225 1226 SETUPX_FreeSubStrings(pSub);1227 }1228 HeapFree(GetProcessHeap(), 0, pEntries);1229 return OK;1230 }
Note:
See TracChangeset
for help on using the changeset viewer.