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.

298 lines
7.4 KiB

  1. /* filedlgs.c - Handles the Windows 3.1 common dialogs.
  2. *
  3. * Created by Microsoft Corporation.
  4. */
  5. #include "packager.h"
  6. #include <commdlg.h>
  7. static CHAR szCustFilterSpec[CBFILTERMAX];
  8. static CHAR szFilterSpec[CBFILTERMAX];
  9. static CHAR szLinkCaption[CBMESSAGEMAX];
  10. static CHAR szImportFile[CBMESSAGEMAX];
  11. static CHAR szExportFile[CBMESSAGEMAX];
  12. static OPENFILENAME gofn;
  13. static VOID AddExtension(LPOPENFILENAME lpOFN);
  14. /* OfnInit() - Initializes the standard file dialog gofn structure.
  15. */
  16. VOID
  17. OfnInit(
  18. VOID
  19. )
  20. {
  21. LPSTR lpstr;
  22. gofn.lStructSize = sizeof(OPENFILENAME);
  23. gofn.hInstance = ghInst;
  24. gofn.nMaxCustFilter = CBFILTERMAX;
  25. gofn.nMaxFile = CBPATHMAX;
  26. gofn.lCustData = 0;
  27. gofn.lpfnHook = NULL;
  28. gofn.lpTemplateName = NULL;
  29. gofn.lpstrFileTitle = NULL;
  30. LoadString(ghInst, IDS_IMPORTFILE, szImportFile, CBMESSAGEMAX);
  31. LoadString(ghInst, IDS_EXPORTFILE, szExportFile, CBMESSAGEMAX);
  32. LoadString(ghInst, IDS_CHANGELINK, szLinkCaption, CBMESSAGEMAX);
  33. LoadString(ghInst, IDS_ALLFILTER, szFilterSpec, CBFILTERMAX);
  34. StringCchCat(szFilterSpec, ARRAYSIZE(szFilterSpec), "*.*");
  35. }
  36. /* OfnGetName() - Calls the standard file dialogs to get a file name
  37. */
  38. BOOL
  39. OfnGetName(
  40. HWND hwnd,
  41. UINT msg
  42. )
  43. {
  44. gofn.hwndOwner = hwnd;
  45. gofn.nFilterIndex = 1;
  46. gofn.lpstrCustomFilter = szCustFilterSpec;
  47. gofn.lpstrDefExt = NULL;
  48. gofn.lpstrFile = gszFileName;
  49. gofn.lpstrFilter = szFilterSpec;
  50. gofn.lpstrInitialDir = NULL;
  51. gofn.Flags = OFN_HIDEREADONLY;
  52. Normalize(gszFileName);
  53. switch (msg)
  54. {
  55. case IDM_IMPORT:
  56. gofn.lpstrTitle = szImportFile;
  57. gofn.Flags |= OFN_FILEMUSTEXIST;
  58. return GetOpenFileName(&gofn);
  59. case IDM_EXPORT:
  60. gofn.lpstrTitle = szExportFile;
  61. gofn.Flags |= (OFN_PATHMUSTEXIST | OFN_NOREADONLYRETURN);
  62. return GetSaveFileName(&gofn);
  63. default:
  64. break;
  65. }
  66. return FALSE;
  67. }
  68. /* OfnGetNewLinkName() - Sets up the "Change Link..." dialog box
  69. */
  70. HANDLE
  71. OfnGetNewLinkName(
  72. HWND hwnd,
  73. HANDLE hData
  74. )
  75. {
  76. BOOL fSuccess = FALSE;
  77. HANDLE hData2 = NULL;
  78. HANDLE hData3 = NULL;
  79. LPSTR lpstrData = NULL;
  80. LPSTR lpstrFile = NULL;
  81. LPSTR lpstrLink = NULL;
  82. LPSTR lpstrPath = NULL;
  83. LPSTR lpstrTemp = NULL;
  84. CHAR szDocFile[CBPATHMAX];
  85. CHAR szDocPath[CBPATHMAX];
  86. CHAR szServerFilter[4 * CBPATHMAX];
  87. // this may have to GlobalAlloc(), if a class supports
  88. // multiple extensions, like Pbrush then we could be in
  89. // trouble. I covered PBRUSH case by making array size 256
  90. // Get the link information
  91. if (!(lpstrData = GlobalLock(hData)))
  92. goto Error;
  93. // Figure out the link's path name and file name
  94. lpstrTemp = lpstrData;
  95. while (*lpstrTemp++)
  96. ;
  97. lpstrPath = lpstrFile = lpstrTemp;
  98. while (*(lpstrTemp = CharNext(lpstrTemp)))
  99. {
  100. if (*lpstrTemp == '\\')
  101. lpstrFile = lpstrTemp + 1;
  102. }
  103. // Copy the document name
  104. StringCchCopy(szDocFile, ARRAYSIZE(szDocFile), lpstrFile);
  105. *(lpstrFile - 1) = 0;
  106. // Copy the path name
  107. StringCchCopy(szDocPath, ARRAYSIZE(szDocPath), ((lpstrPath != lpstrFile) ? lpstrPath : ""));
  108. // If no directory, be sure the path points to the root
  109. if (lstrlen(szDocPath) == 2)
  110. StringCchCat(szDocPath, ARRAYSIZE(szDocPath), "\\");
  111. if (lpstrPath != lpstrFile) /* Restore the backslash */
  112. *(lpstrFile - 1) = '\\';
  113. while (*lpstrFile != '.' && *lpstrFile) /* Get the extension */
  114. lpstrFile++;
  115. // Make a filter that respects the link's class name
  116. gofn.hwndOwner = hwnd;
  117. gofn.nFilterIndex = RegMakeFilterSpec(lpstrData, lpstrFile, szServerFilter);
  118. gofn.lpstrDefExt = NULL;
  119. gofn.lpstrFile = szDocFile;
  120. gofn.lpstrFilter = szServerFilter;
  121. gofn.lpstrInitialDir = szDocPath;
  122. gofn.lpstrTitle = szLinkCaption;
  123. gofn.lpstrCustomFilter = szCustFilterSpec;
  124. gofn.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST;
  125. // If we get a file...
  126. if (GetOpenFileName(&gofn))
  127. {
  128. if (!(hData2 = GlobalAlloc(GMEM_ZEROINIT, CBPATHMAX *
  129. 2)) || !(lpstrLink = lpstrTemp = GlobalLock(hData2)))
  130. goto Error;
  131. // ...add on the correct extension
  132. AddExtension(&gofn);
  133. // ... copy the server name
  134. while (*lpstrTemp++ = *lpstrData++)
  135. ;
  136. // ... copy the document name
  137. lstrcpy(lpstrTemp, szDocFile);
  138. lpstrTemp += lstrlen(lpstrTemp) + 1;
  139. lpstrData += lstrlen(lpstrData) + 1;
  140. // ... copy the item name
  141. while (*lpstrTemp++ = *lpstrData++)
  142. ;
  143. *lpstrTemp = 0;
  144. // ... and compress the memory block to minimal size
  145. GlobalUnlock(hData2);
  146. hData3 = GlobalReAlloc(hData2, (DWORD)(lpstrTemp - lpstrLink + 1), 0);
  147. if (!hData3)
  148. hData3 = hData2;
  149. fSuccess = TRUE;
  150. }
  151. Error:
  152. if (!fSuccess)
  153. {
  154. if (lpstrLink)
  155. GlobalUnlock(hData2);
  156. if (hData2)
  157. GlobalFree(hData2);
  158. hData3 = NULL;
  159. }
  160. if (lpstrData)
  161. GlobalUnlock(hData);
  162. return hData3;
  163. }
  164. /* Normalize() - Removes the path specification from the file name.
  165. *
  166. * Note: It isn't possible to get "<drive>:<filename>" as input because
  167. * the path received will always be fully qualified.
  168. */
  169. VOID
  170. Normalize(
  171. LPSTR lpstrFile
  172. )
  173. {
  174. LPSTR lpstrBackslash = NULL;
  175. LPSTR lpstrTemp = lpstrFile;
  176. BOOL fInQuote = FALSE;
  177. BOOL fQState = FALSE;
  178. while (*lpstrTemp)
  179. {
  180. if (*lpstrTemp == CHAR_QUOTE)
  181. fInQuote = !fInQuote;
  182. if (*lpstrTemp == '\\') {
  183. fQState = fInQuote;
  184. lpstrBackslash = lpstrTemp;
  185. }
  186. if (gbDBCS)
  187. {
  188. lpstrTemp = CharNext(lpstrTemp);
  189. }
  190. else
  191. {
  192. lpstrTemp++;
  193. }
  194. }
  195. if (lpstrBackslash) {
  196. if (fQState)
  197. *lpstrFile++ = CHAR_QUOTE;
  198. MoveMemory(lpstrFile, lpstrBackslash + 1,
  199. lstrlen(lpstrBackslash) * sizeof(lpstrBackslash[0]) );
  200. }
  201. }
  202. /* AddExtension() - Adds the extension corresponding to the filter dropdown.
  203. */
  204. static VOID
  205. AddExtension(
  206. LPOPENFILENAME lpOFN
  207. )
  208. {
  209. LPSTR lpstrFilter = (LPSTR)lpOFN->lpstrFilter;
  210. // If the user didn't specify an extension, use the default
  211. if (lpOFN->nFileExtension == (UINT)lstrlen(lpOFN->lpstrFile)
  212. && lpOFN->nFilterIndex)
  213. {
  214. // Skip to the appropriate filter
  215. while (*lpstrFilter && --lpOFN->nFilterIndex)
  216. {
  217. while (*lpstrFilter++)
  218. ;
  219. while (*lpstrFilter++)
  220. ;
  221. }
  222. // If we got to the filter, retrieve the extension
  223. if (*lpstrFilter)
  224. {
  225. while (*lpstrFilter++)
  226. ;
  227. lpstrFilter++;
  228. // Copy the extension
  229. if (lpstrFilter[1] != '*')
  230. lstrcat(lpOFN->lpstrFile, lpstrFilter);
  231. }
  232. }
  233. }