Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

367 lines
12 KiB

  1. /****************************************************************************\
  2. MAIN.C / OPK Wizard (OPKWIZ.EXE)
  3. Microsoft Confidential
  4. Copyright (c) Microsoft Corporation 1999
  5. All rights reserved
  6. Main source file for the OPK Wizard. Contains WinMain() and global
  7. variable declarations.
  8. 4/99 - Jason Cohen (JCOHEN)
  9. Added this new main source file for the OPK Wizard as part of the
  10. Millennium rewrite.
  11. 09/2000 - Stephen Lodwick (STELO)
  12. Ported OPK Wizard to Whistler
  13. \****************************************************************************/
  14. //
  15. // Include File(s):
  16. //
  17. #include <tchar.h>
  18. #include "opklib.h"
  19. #include "resource.h"
  20. //
  21. // Global Variable(s):
  22. //
  23. TCHAR g_szSource[MAX_PATH] = NULLSTR;
  24. BOOL g_bQuiet = FALSE;
  25. STRRES g_srLangs[] =
  26. {
  27. { _T("ENG"), IDS_ENG },
  28. { _T("GER"), IDS_GER },
  29. { _T("ARA"), IDS_ARA },
  30. { _T("CHH"), IDS_CHH },
  31. { _T("CHT"), IDS_CHT },
  32. { _T("CHS"), IDS_CHS },
  33. { _T("HEB"), IDS_HEB },
  34. { _T("JPN"), IDS_JPN },
  35. { _T("KOR"), IDS_KOR },
  36. { _T("BRZ"), IDS_BRZ },
  37. { _T("CAT"), IDS_CAT },
  38. { _T("CZE"), IDS_CZE },
  39. { _T("DAN"), IDS_DAN },
  40. { _T("DUT"), IDS_DUT },
  41. { _T("FIN"), IDS_FIN },
  42. { _T("FRN"), IDS_FRN },
  43. { _T("GRK"), IDS_GRK },
  44. { _T("HUN"), IDS_HUN },
  45. { _T("ITN"), IDS_ITN },
  46. { _T("NOR"), IDS_NOR },
  47. { _T("POL"), IDS_POL },
  48. { _T("POR"), IDS_POR },
  49. { _T("RUS"), IDS_RUS },
  50. { _T("SPA"), IDS_SPA },
  51. { _T("SWE"), IDS_SWE },
  52. { _T("TRK"), IDS_TRK },
  53. { NULL, 0 },
  54. };
  55. //
  56. // Internal Defined Value(s):
  57. //
  58. #define FILE_INF _T("langinst.inf")
  59. #define DIR_LANG _T("lang")
  60. #define INF_SEC_FILES _T("files")
  61. #define INF_SEC_LANG _T("strings")
  62. #define INF_KEY_LANG _T("lang")
  63. #define COPYFILE_FLAG_RENAME 0x00000001
  64. #define REG_KEY_OPK _T("SOFTWARE\\Microsoft\\OPK")
  65. #define REG_KEY_OPK_LANGS REG_KEY_OPK _T("\\Langs")
  66. #define REG_VAL_PATH _T("Path")
  67. #define STR_OPT_QUIET _T("quiet")
  68. //
  69. // Internal Function Prototype(s):
  70. //
  71. static DWORD InstallLang(LPTSTR lpszInfFile, LPTSTR lpszSrcRoot, LPTSTR lpszDstRoot);
  72. static BOOL ParseCmdLine();
  73. //
  74. // Main Function:
  75. //
  76. int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
  77. {
  78. int nReturn = 0;
  79. if ( ParseCmdLine() && g_szSource[0] )
  80. {
  81. TCHAR szInfFile[MAX_PATH],
  82. szDestination[MAX_PATH] = NULLSTR,
  83. szLang[32] = NULLSTR;
  84. LPTSTR lpLang;
  85. HKEY hKey;
  86. // Figure out our destination is based on the OPK tools install path.
  87. //
  88. if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE, REG_KEY_OPK, 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS )
  89. {
  90. DWORD dwType,
  91. dwSize = AS(szDestination);
  92. if ( ( RegQueryValueEx(hKey, REG_VAL_PATH, NULL, &dwType, (LPBYTE) szDestination, &dwSize) != ERROR_SUCCESS ) ||
  93. ( dwType != REG_SZ ) )
  94. {
  95. szDestination[0] = NULLCHR;
  96. }
  97. RegCloseKey(hKey);
  98. }
  99. // Create the path to the inf file we need on the source.
  100. //
  101. lstrcpyn(szInfFile, g_szSource,AS(szInfFile));
  102. AddPathN(szInfFile, FILE_INF,AS(szInfFile));
  103. // Make sure we have the source file and destination directory and lang.
  104. //
  105. if ( ( szDestination[0] ) &&
  106. ( DirectoryExists(szDestination) ) &&
  107. ( FileExists(szInfFile) ) &&
  108. ( GetPrivateProfileString(INF_SEC_LANG, INF_KEY_LANG, NULLSTR, szLang, AS(szLang), szInfFile) ) &&
  109. ( szLang[0] ) &&
  110. ( lpLang = AllocateStrRes(NULL, g_srLangs, AS(g_srLangs), szLang, NULL) ) )
  111. {
  112. // Now make sure the actually want to instlall it.
  113. //
  114. if ( g_bQuiet || ( MsgBox(NULL, IDS_ASK_INSTALL, IDS_APPNAME, MB_ICONQUESTION | MB_YESNO, lpLang) == IDYES ) )
  115. {
  116. // Now finish creating the root destination path.
  117. //
  118. AddPathN(szDestination, DIR_LANG,AS(szDestination));
  119. AddPathN(szDestination, szLang,AS(szDestination));
  120. // Now actually copy the files.
  121. //
  122. if ( nReturn = InstallLang(szInfFile, g_szSource, szDestination) )
  123. {
  124. // Just return 1 for success.
  125. //
  126. nReturn = 1;
  127. // Set a registry key so we know that the tools for this lang are installed.
  128. //
  129. if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE, REG_KEY_OPK_LANGS, 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS )
  130. {
  131. DWORD dwVal = 1;
  132. RegSetValueEx(hKey, szLang, 0, REG_DWORD, (LPBYTE) &dwVal, sizeof(DWORD));
  133. RegCloseKey(hKey);
  134. }
  135. }
  136. else
  137. {
  138. // Error copying files.
  139. //
  140. MsgBox(NULL, IDS_ERR_FILECOPY, IDS_APPNAME, MB_ERRORBOX, UPPER(szDestination[0]));
  141. }
  142. }
  143. FREE(lpLang);
  144. }
  145. }
  146. return nReturn;
  147. }
  148. //
  149. // Internal Function(s):
  150. //
  151. static DWORD InstallLang(LPTSTR lpszInfFile, LPTSTR lpszSrcRoot, LPTSTR lpszDstRoot)
  152. {
  153. HINF hInf;
  154. DWORD dwErr,
  155. dwRet = 0;
  156. BOOL bRet = TRUE;
  157. // Open our inf that has all the data we need.
  158. //
  159. if ( (hInf = SetupOpenInfFile(lpszInfFile, NULL, INF_STYLE_WIN4, &dwErr)) != INVALID_HANDLE_VALUE )
  160. {
  161. BOOL bLoop;
  162. INFCONTEXT InfContext;
  163. // Loop thru each line in the section we are searching.
  164. //
  165. for ( bLoop = SetupFindFirstLine(hInf, INF_SEC_FILES, NULL, &InfContext);
  166. bLoop && bRet;
  167. bLoop = SetupFindNextLine(&InfContext, &InfContext) )
  168. {
  169. DWORD dwFlags = 0;
  170. LPTSTR lpszSrcName = NULL,
  171. lpszDstName = NULL;
  172. TCHAR szSrcFile[MAX_PATH] = NULLSTR,
  173. szDstFile[MAX_PATH] = NULLSTR,
  174. szSrcFull[MAX_PATH] = NULLSTR,
  175. szDstFull[MAX_PATH] = NULLSTR,
  176. szSrcPath[MAX_PATH],
  177. szDstPath[MAX_PATH];
  178. // Get the source path and filename.
  179. //
  180. if ( !SetupGetStringField(&InfContext, 1, szSrcFile, AS(szSrcFile), NULL) )
  181. szSrcFile[0] = NULLCHR;
  182. // Get the destination path.
  183. //
  184. if ( !SetupGetStringField(&InfContext, 2, szDstFile, AS(szDstFile), NULL) )
  185. szDstFile[0] = NULLCHR;
  186. // Get any flags passed in.
  187. //
  188. if ( !SetupGetIntField(&InfContext, 3, &dwFlags) )
  189. dwFlags = 0;
  190. // Make sure we have the required data in this line.
  191. //
  192. if ( szSrcFile[0] && szDstFile[0] )
  193. {
  194. // Create the full path of the source file.
  195. //
  196. lstrcpyn(szSrcPath, lpszSrcRoot, AS(szSrcPath));
  197. AddPathN(szSrcPath, szSrcFile,AS(szSrcPath));
  198. if ( GetFullPathName(szSrcPath, AS(szSrcFull), szSrcFull, &lpszSrcName) &&
  199. szSrcFull[0] &&
  200. lpszSrcName &&
  201. FileExists(szSrcFull) )
  202. {
  203. // If the destination is NULL or empty, we just want a file count.
  204. //
  205. if ( lpszDstRoot && *lpszDstRoot )
  206. {
  207. // Create the full path of the destination directory.
  208. //
  209. lstrcpyn(szDstPath, lpszDstRoot,AS(szDstPath));
  210. AddPathN(szDstPath, szDstFile,AS(szDstPath));
  211. if ( !(dwFlags & COPYFILE_FLAG_RENAME) )
  212. AddPathN(szDstPath, lpszSrcName,AS(szDstPath));
  213. if ( GetFullPathName(szDstPath, AS(szDstFull), szDstFull, &lpszDstName) &&
  214. szDstFull[0] &&
  215. lpszDstName )
  216. {
  217. // We want just the path part of the destination file name.
  218. //
  219. lstrcpyn(szDstPath, szDstFull, (int)(lpszDstName - szDstFull));
  220. // Now make sure the path exists and actually copy the file.
  221. //
  222. if ( ( DirectoryExists(szDstPath) || CreatePath(szDstPath) ) &&
  223. ( CopyResetFile(szSrcFull, szDstFull) ) )
  224. {
  225. dwRet++;
  226. }
  227. else
  228. bRet = FALSE;
  229. }
  230. }
  231. else
  232. dwRet++;
  233. }
  234. }
  235. }
  236. // We are done, so close the INF file.
  237. //
  238. SetupCloseInfFile(hInf);
  239. }
  240. return bRet ? dwRet : 0;
  241. }
  242. static BOOL ParseCmdLine()
  243. {
  244. DWORD dwArgs;
  245. LPTSTR *lpArgs;
  246. BOOL bError = FALSE;
  247. if ( (dwArgs = GetCommandLineArgs(&lpArgs) ) && lpArgs )
  248. {
  249. LPTSTR lpArg;
  250. DWORD dwArg;
  251. // We want to skip over the first argument (it is the path
  252. // to the command being executed.
  253. //
  254. if ( dwArgs > 1 )
  255. {
  256. dwArg = 1;
  257. lpArg = *(lpArgs + dwArg);
  258. }
  259. else
  260. lpArg = NULL;
  261. // Loop through all the arguments.
  262. //
  263. while ( lpArg && !bError )
  264. {
  265. // Now we check to see if the first char is a dash or not.
  266. //
  267. if ( ( *lpArg == _T('-') ) ||
  268. ( *lpArg == _T('/') ) )
  269. {
  270. LPTSTR lpOption = CharNext(lpArg);
  271. //
  272. // This is where you add command line options that start with a dash (-).
  273. //
  274. // Set bError if you don't recognize the command line option (unless you
  275. // want to just ignore it and continue).
  276. //
  277. if ( LSTRCMPI(lpOption, STR_OPT_QUIET) == 0 )
  278. g_bQuiet = TRUE;
  279. else
  280. bError = TRUE;
  281. }
  282. else if ( *lpArg )
  283. {
  284. //
  285. // This is where you would read any command line parameters that are just passed
  286. // in on the command line w/o any proceeding characters (like - or /).
  287. //
  288. // Set bError if you don't have any of these types of parameters (unless you
  289. // want to just ignore it and continue).
  290. //
  291. if ( g_szSource[0] == NULLCHR )
  292. lstrcpy(g_szSource, lpArg);
  293. else
  294. bError = TRUE;
  295. }
  296. // Setup the pointer to the next argument in the command line.
  297. //
  298. if ( ++dwArg < dwArgs )
  299. lpArg = *(lpArgs + dwArg);
  300. else
  301. lpArg = NULL;
  302. }
  303. // Make sure to free the two buffers allocated by the GetCommandLineArgs() function.
  304. //
  305. FREE(*lpArgs);
  306. FREE(lpArgs);
  307. }
  308. return !bError;
  309. }