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.

315 lines
11 KiB

  1. #include "diskcopy.h"
  2. #include "ids.h"
  3. #include "help.h"
  4. #include "makeboot.h"
  5. #include <strsafe.h>
  6. // todo: add check that we can only make boot disks on 3.5 disks
  7. UINT _GetClassFromCP (UINT iOEMCP)
  8. {
  9. for (int i = 0; i < ARRAYSIZE(rgCPtoClassMap); i++)
  10. {
  11. if (iOEMCP == rgCPtoClassMap[i].iCP)
  12. {
  13. return rgCPtoClassMap[i].iClass;
  14. }
  15. }
  16. return 0; // default
  17. }
  18. UINT _GetKBFromLangId(WORD wLangId)
  19. {
  20. for (int i = 0; i < ARRAYSIZE(rgLangIdtoKBMap); i++)
  21. {
  22. if (wLangId == rgLangIdtoKBMap[i].wLangId)
  23. {
  24. return rgLangIdtoKBMap[i].iKB;
  25. }
  26. }
  27. // if we don't get an exact match, try to match just the primary lang id
  28. for (int i = 0; i < ARRAYSIZE(rgLangIdtoKBMap); i++)
  29. {
  30. if (PRIMARYLANGID(wLangId) == PRIMARYLANGID(rgLangIdtoKBMap[i].wLangId))
  31. {
  32. return rgLangIdtoKBMap[i].iKB;
  33. }
  34. }
  35. // if all else fails, default to US keyboard
  36. return KEYBOARD_US;
  37. }
  38. UINT _GetClassFromKB (UINT iKB)
  39. {
  40. for (int i = 0; i < ARRAYSIZE(rgKBtoClassMap); i++)
  41. {
  42. if (iKB == rgKBtoClassMap[i].iKB)
  43. {
  44. return rgKBtoClassMap[i].iClass;
  45. }
  46. }
  47. return KBCLASS_1; // default
  48. }
  49. BOOL _GetKeyboardID(UINT iKB, UINT* piID)
  50. {
  51. BOOL fRet = FALSE;
  52. switch (iKB)
  53. {
  54. case KEYBOARD_HE:
  55. *piID = 400;
  56. fRet = TRUE;
  57. break;
  58. case KEYBOARD_TR:
  59. *piID = 179;
  60. fRet = TRUE;
  61. break;
  62. }
  63. return fRet;
  64. }
  65. typedef struct {
  66. UINT OEMCP;
  67. UINT KB;
  68. } LANGSETTINGS;
  69. HRESULT _GetAutoexecOEMCP(HINSTANCE hInstance, LANGSETTINGS* pls, LPSTR pszBuffer, UINT cchBuffer)
  70. {
  71. return StringCchPrintfA(pszBuffer, cchBuffer, "%d", pls->OEMCP);
  72. }
  73. HRESULT _GetAutoexecEGAFname(HINSTANCE hInstance, LANGSETTINGS* pls, LPSTR pszBuffer, UINT cchBuffer)
  74. {
  75. LoadStringA(hInstance, IDS_DOSBOOTDISK_AUTOEXEC_EGA_1 + _GetClassFromCP(pls->OEMCP), pszBuffer, cchBuffer);
  76. return S_OK;
  77. }
  78. HRESULT _GetConfigSysEGA(HINSTANCE hInstance, LANGSETTINGS* pls, LPSTR pszBuffer, UINT cchBuffer)
  79. {
  80. LoadStringA(hInstance, IDS_DOSBOOTDISK_CONFIG_EGA_1 + _GetClassFromCP(pls->OEMCP), pszBuffer, cchBuffer);
  81. return S_OK;
  82. }
  83. HRESULT _GetAutoexecKeybCode(HINSTANCE hInstance, LANGSETTINGS* pls, LPSTR pszBuffer, UINT cchBuffer)
  84. {
  85. LoadStringA(hInstance, IDS_DOSBOOTDISK_KEYBOARD_CODE_US + pls->KB, pszBuffer, cchBuffer);
  86. return S_OK;
  87. }
  88. HRESULT _GetAutoexecKeybFname(HINSTANCE hInstance, LANGSETTINGS* pls, LPSTR pszBuffer, UINT cchBuffer)
  89. {
  90. LoadStringA(hInstance, IDS_DOSBOOTDISK_KEYBOARD_FNAME_1 + _GetClassFromKB(pls->KB), pszBuffer, cchBuffer);
  91. return S_OK;
  92. }
  93. HRESULT _GetConfigKeybID(HINSTANCE hInstance, LANGSETTINGS* pls, LPSTR pszBuffer, UINT cchBuffer)
  94. {
  95. HRESULT hr = E_FAIL;
  96. UINT iID;
  97. if (_GetKeyboardID(pls->KB, &iID))
  98. {
  99. hr = StringCchPrintfA(pszBuffer, cchBuffer, "%d", iID);
  100. }
  101. return hr;
  102. }
  103. HANDLE _CreateSystemFile(HINSTANCE hInstance, UINT iDrive, UINT id)
  104. {
  105. HANDLE handle = INVALID_HANDLE_VALUE;
  106. TCHAR szFname[MAX_PATH];
  107. LoadString(hInstance, id, szFname, ARRAYSIZE(szFname));
  108. TCHAR szPath[MAX_PATH];
  109. PathBuildRoot(szPath, iDrive);
  110. if (PathAppend(szPath, szFname))
  111. {
  112. handle = CreateFile(szPath, GENERIC_WRITE | GENERIC_READ, 0,
  113. NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
  114. }
  115. return handle;
  116. }
  117. HRESULT _WriteAutoexec(HINSTANCE hInstance, UINT iDrive, LANGSETTINGS* pls)
  118. {
  119. HRESULT hr = E_FAIL;
  120. HANDLE hFile = _CreateSystemFile(hInstance, iDrive, IDS_DOSBOOTDISK_AUTOEXEC_FNAME);
  121. if (INVALID_HANDLE_VALUE != hFile)
  122. {
  123. if (437 != pls->OEMCP && // use empty autoexec.bat on US locale
  124. 932 != pls->OEMCP && // use empty autoexec.bat on Japanese locale
  125. 949 != pls->OEMCP && // use empty autoexec.bat on Korean locale
  126. 936 != pls->OEMCP && // use empty autoexec.bat on CHS locale
  127. 950 != pls->OEMCP) // use empty autoexec.bat on CHT locale
  128. {
  129. CHAR aszBufferOEMCP[4];
  130. CHAR aszBufferEGAFname[13];
  131. CHAR aszBufferKeybCode[3];
  132. CHAR aszBufferKeybFname[13];
  133. if (SUCCEEDED(_GetAutoexecOEMCP(hInstance, pls, aszBufferOEMCP, ARRAYSIZE(aszBufferOEMCP))) &&
  134. SUCCEEDED(_GetAutoexecEGAFname(hInstance, pls, aszBufferEGAFname, ARRAYSIZE(aszBufferEGAFname))) &&
  135. SUCCEEDED(_GetAutoexecKeybCode(hInstance, pls, aszBufferKeybCode, ARRAYSIZE(aszBufferKeybCode))) &&
  136. SUCCEEDED(_GetAutoexecKeybFname(hInstance, pls, aszBufferKeybFname, ARRAYSIZE(aszBufferKeybFname))))
  137. {
  138. CHAR aszTemplate[1000];
  139. CHAR aszKeyboardID[5];
  140. if (SUCCEEDED(_GetConfigKeybID(hInstance, pls, aszKeyboardID, ARRAYSIZE(aszKeyboardID))))
  141. {
  142. LoadStringA(hInstance, IDS_DOSBOOTDISK_AUTOEXEC_TEMPLATE_WITH_CODE, aszTemplate, ARRAYSIZE(aszTemplate));
  143. }
  144. else
  145. {
  146. LoadStringA(hInstance, IDS_DOSBOOTDISK_AUTOEXEC_TEMPLATE, aszTemplate, ARRAYSIZE(aszTemplate));
  147. }
  148. CHAR aszBuffer[1000];
  149. hr = StringCchPrintfA(aszBuffer, ARRAYSIZE(aszBuffer), aszTemplate,
  150. aszBufferOEMCP, aszBufferEGAFname, aszBufferOEMCP,
  151. aszBufferKeybCode, aszBufferKeybFname, aszKeyboardID);
  152. if (SUCCEEDED(hr))
  153. {
  154. DWORD cbWritten;
  155. WriteFile(hFile, aszBuffer, sizeof(CHAR) * lstrlenA(aszBuffer), &cbWritten, NULL);
  156. }
  157. }
  158. }
  159. CloseHandle(hFile);
  160. }
  161. return hr;
  162. }
  163. HRESULT _WriteConfigSys(HINSTANCE hInstance, UINT iDrive, LANGSETTINGS* pls)
  164. {
  165. HRESULT hr = E_FAIL;
  166. HANDLE hFile = _CreateSystemFile(hInstance, iDrive, IDS_DOSBOOTDISK_CONFIG_FNAME);
  167. if (INVALID_HANDLE_VALUE != hFile)
  168. {
  169. if (437 != pls->OEMCP && // use empty config.sys on US locale
  170. 932 != pls->OEMCP && // use empty config.sys on Japanese locale
  171. 949 != pls->OEMCP && // use empty config.sys on Korean locale
  172. 936 != pls->OEMCP && // use empty config.sys on CHS locale
  173. 950 != pls->OEMCP) // use empty config.sys on CHT locale
  174. {
  175. CHAR aszTemplate[1000];
  176. CHAR aszBufferEGA[64];
  177. LoadStringA(hInstance, IDS_DOSBOOTDISK_CONFIG_TEMPLATE, aszTemplate, ARRAYSIZE(aszTemplate));
  178. if (SUCCEEDED(_GetConfigSysEGA(hInstance, pls, aszBufferEGA, ARRAYSIZE(aszBufferEGA))))
  179. {
  180. CHAR aszBuffer[1000];
  181. hr = StringCchPrintfA(aszBuffer, ARRAYSIZE(aszBuffer), aszTemplate, aszBufferEGA);
  182. if (SUCCEEDED(hr))
  183. {
  184. DWORD cbWritten;
  185. WriteFile(hFile, aszBuffer, sizeof(CHAR) * lstrlenA(aszBuffer), &cbWritten, NULL);
  186. hr = S_OK;
  187. }
  188. }
  189. }
  190. CloseHandle(hFile);
  191. }
  192. return hr;
  193. }
  194. HRESULT _LoadUISettings (LANGSETTINGS* pls)
  195. {
  196. pls->OEMCP = GetOEMCP();
  197. pls->KB = _GetKBFromLangId(LOWORD(GetKeyboardLayout(0)));
  198. if (KBCLASS_BLANK == _GetClassFromKB(pls->KB))
  199. {
  200. pls->KB = _GetKBFromLangId(GetSystemDefaultUILanguage());
  201. }
  202. return S_OK;
  203. }
  204. HRESULT _WriteDiskImage(HINSTANCE hInstance, UINT iDrive, BOOL* pfCancelled, FMIFS_CALLBACK pCallback)
  205. {
  206. HRESULT hr = E_FAIL;
  207. HRSRC hrsrc = FindResourceW(hInstance, MAKEINTRESOURCEW(IDX_DOSBOOTDISK), L"BINFILE");
  208. if (hrsrc)
  209. {
  210. HGLOBAL hglob = LoadResource(hInstance, hrsrc);
  211. if (hglob)
  212. {
  213. BYTE* pbPtr = (BYTE*)hglob;
  214. DWORD cbGlob = SizeofResource(hInstance, hrsrc);
  215. TCHAR szDrive[] = TEXT("\\\\.\\a:");
  216. szDrive[4] += (TCHAR)iDrive;
  217. HANDLE hFloppyDrive = CreateFile(szDrive, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
  218. OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN | FILE_FLAG_WRITE_THROUGH, NULL );
  219. if (INVALID_HANDLE_VALUE == hFloppyDrive)
  220. {
  221. pCallback(FmIfsAccessDenied, 0, NULL);
  222. }
  223. else
  224. {
  225. hr = S_OK;
  226. CHAR TrackBuffer[TRACK_SIZE];
  227. DWORD cBytesRead = 0;
  228. DWORD cBytesWritten = 0;
  229. INT iCurrentTrack;
  230. for( iCurrentTrack = 0; iCurrentTrack < TRACKS_ON_DISK && SUCCEEDED(hr) && !*pfCancelled; iCurrentTrack++ )
  231. {
  232. DWORD cbRead;
  233. cbRead = __min(cbGlob, TRACK_SIZE);
  234. CopyMemory(TrackBuffer, pbPtr, cbRead);
  235. pbPtr += cbRead;
  236. cbGlob -= cbRead;
  237. if( ! WriteFile( hFloppyDrive, TrackBuffer, cbRead, &cBytesWritten, NULL ) )
  238. {
  239. pCallback(FmIfsIoError, 0, NULL);
  240. hr = E_FAIL;
  241. }
  242. else
  243. {
  244. FMIFS_PERCENT_COMPLETE_INFORMATION pci;
  245. pci.PercentCompleted = (100 * iCurrentTrack) / TRACKS_ON_DISK;
  246. pCallback(FmIfsPercentCompleted, sizeof(FMIFS_PERCENT_COMPLETE_INFORMATION), &pci);
  247. }
  248. }
  249. CloseHandle(hFloppyDrive);
  250. }
  251. FreeResource(hglob);
  252. }
  253. }
  254. return hr;
  255. }
  256. HRESULT MakeBootDisk(HINSTANCE hInstance, UINT iDrive, BOOL* pfCancelled, FMIFS_CALLBACK pCallback)
  257. {
  258. HRESULT hr = _WriteDiskImage(hInstance, iDrive, pfCancelled, pCallback);
  259. // if we didn't cancel or fail, then place autoexec.bat and config.sys on the disk as well
  260. if (SUCCEEDED(hr) && !*pfCancelled)
  261. {
  262. LANGSETTINGS ls;
  263. hr = _LoadUISettings(&ls);
  264. if (SUCCEEDED(hr))
  265. {
  266. _WriteAutoexec(hInstance, iDrive, &ls);
  267. _WriteConfigSys(hInstance, iDrive, &ls);
  268. FMIFS_FINISHED_INFORMATION pfi;
  269. pfi.Success = TRUE;
  270. pCallback(FmIfsFinished, sizeof(FMIFS_FINISHED_INFORMATION), &pfi);
  271. }
  272. }
  273. return hr;
  274. }