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.

365 lines
10 KiB

  1. /*
  2. ** utils.c - Miscellaneous utility routines used in compression / expansion
  3. ** modules. Theoretically these functions are DBCS-enabled.
  4. **
  5. ** Author: DavidDi
  6. */
  7. // Headers
  8. ///////////
  9. #ifndef LZA_DLL
  10. #include <ctype.h>
  11. #include <string.h>
  12. #endif
  13. #include "lz_common.h"
  14. /*
  15. ** char ARG_PTR *ExtractFileName(char ARG_PTR pszPathName);
  16. **
  17. ** Find the file name in a fully specified path name.
  18. **
  19. ** Arguments: pszPathName - path string from which to extract file name
  20. **
  21. ** Returns: char ARG_PTR * - Pointer to file name in pszPathName.
  22. **
  23. ** Globals: none
  24. */
  25. LPWSTR
  26. ExtractFileNameW(
  27. LPWSTR pszPathName)
  28. {
  29. LPWSTR pszLastComponent, psz;
  30. for (pszLastComponent = psz = pszPathName; *psz != L'\0'; psz++)
  31. {
  32. if (*psz == L'\\' || *psz == L':')
  33. pszLastComponent = psz + 1;
  34. }
  35. return(pszLastComponent);
  36. }
  37. CHAR ARG_PTR *ExtractFileName(CHAR ARG_PTR *pszPathName)
  38. {
  39. CHAR ARG_PTR *pszLastComponent, ARG_PTR *psz;
  40. for (pszLastComponent = psz = pszPathName; *psz != '\0'; psz = CharNext(psz))
  41. {
  42. if (! IsDBCSLeadByte(*psz) && (ISSLASH(*psz) || *psz == COLON))
  43. pszLastComponent = CharNext(psz);
  44. }
  45. return(pszLastComponent);
  46. }
  47. /*
  48. ** char ARG_PTR *ExtractExtension(char ARG_PTR *pszFileName);
  49. **
  50. ** Find the extension of a file name.
  51. **
  52. ** Arguments: pszFileName - file name to examine
  53. **
  54. ** Returns: char ARG_PTR * - Pointer to file name extension if one exists.
  55. ** NULL if the file name doesn't include an
  56. ** extension.
  57. **
  58. ** Globals: none
  59. */
  60. LPWSTR
  61. ExtractExtensionW(
  62. LPWSTR pszFileName)
  63. {
  64. WCHAR *psz;
  65. // Make sure we have an isolated file name.
  66. psz = ExtractFileNameW(pszFileName);
  67. while (*psz != L'\0' && *psz != L'.')
  68. psz++;
  69. if (*psz == L'.')
  70. return(psz + 1);
  71. else
  72. return(NULL);
  73. }
  74. CHAR ARG_PTR *ExtractExtension(CHAR ARG_PTR *pszFileName)
  75. {
  76. CHAR ARG_PTR *psz;
  77. // Make sure we have an isolated file name.
  78. psz = ExtractFileName(pszFileName);
  79. while (IsDBCSLeadByte(*psz) || (*psz != '\0' && *psz != PERIOD))
  80. psz = CharNext(psz);
  81. if (*psz == PERIOD)
  82. return(psz + 1);
  83. else
  84. return(NULL);
  85. }
  86. /*
  87. ** void MakePathName(char ARG_PTR *pszPath, char ARG_PTR *pszFileName);
  88. **
  89. ** Append a filename to a path string.
  90. **
  91. ** Arguments: pszPath - path string to which pszFileName will be appended
  92. ** pszFileName - file name to append
  93. **
  94. ** Returns: void
  95. **
  96. ** Globals: none
  97. */
  98. VOID MakePathName(CHAR ARG_PTR *pszPath, CHAR ARG_PTR *pszFileName)
  99. {
  100. CHAR chLastPathChar;
  101. // Make sure we have an isolated file name.
  102. pszFileName = ExtractFileName(pszFileName);
  103. // Dont append to a NULL string or a single ".".
  104. if (*pszFileName != '\0' &&
  105. ! (! IsDBCSLeadByte(pszFileName[0]) && pszFileName[0] == PERIOD &&
  106. ! IsDBCSLeadByte(pszFileName[1]) && pszFileName[1] == '\0'))
  107. {
  108. chLastPathChar = *CharPrev(pszPath, pszPath + STRLEN(pszPath));
  109. //NTRAID:MSKKBUG #3411 Nov.09.93 v-hajimy
  110. if (! ISSLASH(chLastPathChar) && chLastPathChar != COLON)
  111. STRCAT(pszPath, SEP_STR);
  112. STRCAT(pszPath, pszFileName);
  113. }
  114. }
  115. /*
  116. ** char MakeCompressedName(char ARG_PTR *pszFileName);
  117. **
  118. ** Make a file name into the corresponding compressed file name.
  119. **
  120. ** Arguments: pszOriginalName - file name to convert to compressed file name
  121. **
  122. ** Returns: char - Uncompressed file name extension character that was
  123. ** replaced. '\0' if no character needed to be replaced.
  124. **
  125. ** Globals: none
  126. **
  127. ** N.b., assumes pszFileName's buffer is long enough to hold an extra two
  128. ** characters ("._").
  129. **
  130. ** For DBCS filenames, we know we can have at most one DBCS character in the
  131. ** extension. So instead of just blindly replacing the last character of a
  132. ** three-byte extension with an underscore, we replace the last single-byte
  133. ** character with an underscore.
  134. */
  135. #define chEXTENSION_CHARW L'_'
  136. #define pszEXTENSION_STRW L"_"
  137. #define pszNULL_EXTENSIONW L"._"
  138. WCHAR
  139. MakeCompressedNameW(
  140. LPWSTR pszFileName)
  141. {
  142. WCHAR chReplaced = L'\0';
  143. WCHAR ARG_PTR *pszExt;
  144. if ((pszExt = ExtractExtensionW(pszFileName)) != NULL)
  145. {
  146. if (lstrlenW(pszExt) >= 3)
  147. {
  148. chReplaced = pszExt[lstrlenW(pszExt) - 1];
  149. pszExt[lstrlenW(pszExt) - 1] = chEXTENSION_CHARW;
  150. }
  151. else
  152. lstrcatW(pszExt, pszEXTENSION_STRW);
  153. }
  154. else
  155. lstrcatW(pszFileName, pszNULL_EXTENSIONW);
  156. return(chReplaced);
  157. }
  158. CHAR MakeCompressedName(CHAR ARG_PTR *pszFileName)
  159. {
  160. CHAR chReplaced = '\0';
  161. ULONG NameLength = STRLEN( pszFileName );
  162. ULONG DotIndex = NameLength;
  163. while (( DotIndex > 0 ) && ( pszFileName[ --DotIndex ] != '.' )) {
  164. if (( pszFileName[ DotIndex ] == '\\' ) ||
  165. ( pszFileName[ DotIndex ] == ':' )) { // end of filename part of path
  166. DotIndex = 0; // name has no extension
  167. break;
  168. }
  169. }
  170. if ( DotIndex > 0 ) { // name has an extension
  171. if (( NameLength - DotIndex ) <= 3 ) { // extension less than 3 chars
  172. pszFileName[ NameLength++ ] = '_'; // append '_' to extension
  173. pszFileName[ NameLength ] = 0; // terminate
  174. }
  175. else { // extension more than 3 chars
  176. chReplaced = pszFileName[ NameLength - 1 ]; // return original
  177. pszFileName[ NameLength - 1 ] = '_'; // replace last char with '_'
  178. }
  179. }
  180. else { // name has no extension
  181. pszFileName[ NameLength++ ] = '.'; // append '.'
  182. pszFileName[ NameLength++ ] = '_'; // append '_'
  183. pszFileName[ NameLength ] = 0; // terminate
  184. }
  185. return(chReplaced);
  186. }
  187. /*
  188. ** void MakeExpandedName(char ARG_PTR *pszFileName, BYTE byteExtensionChar);
  189. **
  190. ** Create expanded output file name.
  191. **
  192. ** Arguments: pszFileName - expanded file name to change
  193. ** byteExtensionChar - expanded file name extension character to
  194. ** use
  195. **
  196. ** Returns: void
  197. **
  198. ** Globals: none
  199. */
  200. VOID MakeExpandedName(CHAR ARG_PTR *pszFileName, BYTE byteExtensionChar)
  201. {
  202. CHAR ARG_PTR *pszExt;
  203. INT nExtLen;
  204. // Is there any extension to change?
  205. if ((pszExt = ExtractExtension(pszFileName)) != NULL)
  206. {
  207. // Determine case of extension character. Match case of first non-DB
  208. // character in name. If all characters are DB, leave case alone.
  209. if (ISLETTER(byteExtensionChar))
  210. {
  211. // Find first alphabetic character in name.
  212. while (*pszFileName)
  213. {
  214. if (IsDBCSLeadByte(*pszFileName))
  215. pszFileName += 2;
  216. else if (ISLETTER(*pszFileName))
  217. break;
  218. else
  219. pszFileName++;
  220. }
  221. // Here pszFileName points to the first alphabetic character in the
  222. // name or to the null terminator. Set the case of the extension
  223. // character.
  224. if (ISLOWER(*pszFileName))
  225. byteExtensionChar = (BYTE)TOLOWERCASE(byteExtensionChar);
  226. else if (ISUPPER(*pszFileName))
  227. byteExtensionChar = (BYTE)TOUPPERCASE(byteExtensionChar);
  228. }
  229. if ((nExtLen = STRLEN(pszExt)) > 0)
  230. {
  231. // Find the underscore character to replace, if it exists.
  232. // Assert: The underscore is either the last character in the
  233. // extension, or it is the first character in the extension followed
  234. // by a double-byte character.
  235. if (! IsDBCSLeadByte(*pszExt) && *pszExt == chEXTENSION_CHAR &&
  236. IsDBCSLeadByte(pszExt[1]))
  237. // Here the underscore is followed by a double-byte character.
  238. *pszExt = byteExtensionChar;
  239. else
  240. {
  241. // Here the underscore is the last character in the extension, if
  242. // there is an underscore at all.
  243. CHAR ARG_PTR *psz, *pszPrevious;
  244. for (psz = pszPrevious = pszExt; *psz != '\0'; psz = CharNext(psz))
  245. pszPrevious = psz;
  246. if (! IsDBCSLeadByte(*pszPrevious) &&
  247. *pszPrevious == chEXTENSION_CHAR)
  248. *pszPrevious = byteExtensionChar;
  249. }
  250. }
  251. // Get rid of trailing dot with no extension.
  252. if (*pszExt == '\0' && *(pszExt - 1) == PERIOD)
  253. *(pszExt - 1) = '\0';
  254. }
  255. }
  256. /*
  257. ** int CopyDateTimeStamp(INT_PTR doshFrom, INT_PTR doshTo);
  258. **
  259. ** Copy date and time stamp from one file to another.
  260. **
  261. ** Arguments: doshFrom - date and time stamp source DOS file handle
  262. ** doshTo - target DOS file handle
  263. **
  264. ** Returns: TRUE if successful. LZERROR_BADINHANDLE or
  265. ** LZERROR_BADOUTHANDLE if unsuccessful.
  266. **
  267. ** Globals: none
  268. **
  269. ** N.b., stream-style I/O routines like fopen() and fclose() may counter the
  270. ** intended effect of this function. fclose() writes the current date to any
  271. ** file it's called with which was opened in write "w" or append "a" mode.
  272. ** One way to get around this in order to modify the date of a file opened
  273. ** for writing or appending by fopen() is to fclose() the file and fopen() it
  274. ** again in read "r" mode. Then set its date and time stamp with
  275. ** CopyDateTimeStamp().
  276. */
  277. INT CopyDateTimeStamp(INT_PTR doshFrom, INT_PTR doshTo)
  278. {
  279. #ifdef ORGCODE
  280. // DOS prototypes from <dos.h>
  281. extern DWORD _dos_getftime(INT dosh, DWORD *puDate, DWORD *puTime);
  282. extern DWORD _dos_setftime(INT dosh, DWORD uDate, DWORD uTime);
  283. #ifdef LZA_DLL
  284. static
  285. #endif
  286. DWORD uFrom_date, // temporary storage for date
  287. uFrom_time; // and time stamps
  288. if (_dos_getftime(doshFrom, &uFrom_date, &uFrom_time) != 0u)
  289. return((INT)LZERROR_BADINHANDLE);
  290. if (_dos_setftime(doshTo, uFrom_date, uFrom_time) != 0u)
  291. return((INT)LZERROR_BADOUTHANDLE);
  292. #else
  293. FILETIME lpCreationTime, lpLastAccessTime, lpLastWriteTime;
  294. if(!GetFileTime((HANDLE) doshFrom, &lpCreationTime, &lpLastAccessTime,
  295. &lpLastWriteTime)){
  296. return((INT)LZERROR_BADINHANDLE);
  297. }
  298. if(!SetFileTime((HANDLE) doshTo, &lpCreationTime, &lpLastAccessTime,
  299. &lpLastWriteTime)){
  300. return((INT)LZERROR_BADINHANDLE);
  301. }
  302. #endif
  303. return(TRUE);
  304. }