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.

381 lines
11 KiB

  1. #include <nt.h>
  2. #include <ntrtl.h>
  3. #include <nturtl.h>
  4. #include "verpriv.h"
  5. #define DWORDUP(x) (((x)+3) & ~3)
  6. DWORD
  7. APIENTRY
  8. VerFindFileA(
  9. DWORD wFlags,
  10. LPSTR lpszFileName,
  11. LPSTR lpszWinDir,
  12. LPSTR lpszAppDir,
  13. LPSTR lpszCurDir,
  14. PUINT puCurDirLen,
  15. LPSTR lpszDestDir,
  16. PUINT puDestDirLen
  17. )
  18. {
  19. UNICODE_STRING FileName;
  20. UNICODE_STRING WinDir;
  21. UNICODE_STRING AppDir;
  22. UNICODE_STRING CurDir;
  23. UNICODE_STRING DestDir;
  24. ANSI_STRING AnsiString;
  25. NTSTATUS Status;
  26. DWORD CurDirLen = (*puCurDirLen) ? (*puCurDirLen) : 1;
  27. DWORD DestDirLen = (*puDestDirLen) ? (*puDestDirLen) : 1;
  28. CurDirLen = min(MAX_PATH, CurDirLen);
  29. DestDirLen = min(MAX_PATH, DestDirLen);
  30. RtlInitAnsiString(&AnsiString, lpszFileName);
  31. Status = RtlAnsiStringToUnicodeString(&FileName, &AnsiString, TRUE);
  32. if (!NT_SUCCESS(Status)) {
  33. SetLastError(Status);
  34. return VFF_BUFFTOOSMALL;
  35. }
  36. RtlInitAnsiString(&AnsiString, lpszWinDir);
  37. Status = RtlAnsiStringToUnicodeString(&WinDir, &AnsiString, TRUE);
  38. if (!NT_SUCCESS(Status)) {
  39. RtlFreeUnicodeString(&FileName);
  40. SetLastError(Status);
  41. return VFF_BUFFTOOSMALL;
  42. }
  43. RtlInitAnsiString(&AnsiString, lpszAppDir);
  44. Status = RtlAnsiStringToUnicodeString(&AppDir, &AnsiString, TRUE);
  45. if (!NT_SUCCESS(Status)) {
  46. RtlFreeUnicodeString(&FileName);
  47. RtlFreeUnicodeString(&WinDir);
  48. SetLastError(Status);
  49. return VFF_BUFFTOOSMALL;
  50. }
  51. CurDir.MaximumLength = (USHORT)CurDirLen * sizeof(WCHAR);
  52. CurDir.Buffer = RtlAllocateHeap(RtlProcessHeap(), 0, CurDir.MaximumLength);
  53. if (CurDir.Buffer == NULL) {
  54. RtlFreeUnicodeString(&FileName);
  55. RtlFreeUnicodeString(&WinDir);
  56. RtlFreeUnicodeString(&AppDir);
  57. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  58. return VFF_BUFFTOOSMALL;
  59. }
  60. DestDir.MaximumLength = (USHORT)DestDirLen * sizeof(WCHAR);
  61. DestDir.Buffer = RtlAllocateHeap(RtlProcessHeap(), 0, DestDir.MaximumLength);
  62. if (DestDir.Buffer == NULL) {
  63. RtlFreeUnicodeString(&FileName);
  64. RtlFreeUnicodeString(&WinDir);
  65. RtlFreeUnicodeString(&AppDir);
  66. RtlFreeUnicodeString(&CurDir);
  67. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  68. return VFF_BUFFTOOSMALL;
  69. }
  70. Status = VerFindFileW(wFlags,
  71. FileName.Buffer,
  72. WinDir.Buffer,
  73. AppDir.Buffer,
  74. CurDir.Buffer, &CurDirLen,
  75. DestDir.Buffer, &DestDirLen);
  76. if (Status & VFF_BUFFTOOSMALL) {
  77. *lpszCurDir = 0;
  78. *puCurDirLen = CurDirLen;
  79. *lpszDestDir = 0;
  80. *puDestDirLen = DestDirLen;
  81. } else {
  82. CurDir.Length = (USHORT)(sizeof(WCHAR)*CurDirLen);
  83. DestDir.Length = (USHORT)(sizeof(WCHAR)*DestDirLen);
  84. AnsiString.Buffer = lpszCurDir;
  85. AnsiString.MaximumLength = (USHORT)*puCurDirLen;
  86. RtlUnicodeStringToAnsiString(&AnsiString, &CurDir, FALSE);
  87. *puCurDirLen = AnsiString.Length;
  88. AnsiString.Buffer = lpszDestDir;
  89. AnsiString.MaximumLength = (USHORT)*puDestDirLen;
  90. RtlUnicodeStringToAnsiString(&AnsiString, &DestDir, FALSE);
  91. *puDestDirLen = AnsiString.Length;
  92. }
  93. RtlFreeUnicodeString(&FileName);
  94. RtlFreeUnicodeString(&WinDir);
  95. RtlFreeUnicodeString(&AppDir);
  96. RtlFreeUnicodeString(&CurDir);
  97. RtlFreeUnicodeString(&DestDir);
  98. return Status;
  99. }
  100. DWORD
  101. APIENTRY
  102. VerInstallFileA(
  103. DWORD wFlags,
  104. LPSTR lpszSrcFileName,
  105. LPSTR lpszDstFileName,
  106. LPSTR lpszSrcDir,
  107. LPSTR lpszDstDir,
  108. LPSTR lpszCurDir,
  109. LPSTR lpszTmpFile,
  110. PUINT puTmpFileLen
  111. )
  112. {
  113. UNICODE_STRING SrcFileName;
  114. UNICODE_STRING DstFileName;
  115. UNICODE_STRING SrcDir;
  116. UNICODE_STRING CurDir;
  117. UNICODE_STRING DstDir;
  118. UNICODE_STRING TmpFile;
  119. ANSI_STRING AnsiString;
  120. NTSTATUS Status;
  121. DWORD TmpFileLen = (*puTmpFileLen) ? (*puTmpFileLen) : 1;
  122. TmpFileLen = min(MAX_PATH, TmpFileLen);
  123. RtlInitAnsiString(&AnsiString, lpszSrcFileName);
  124. Status = RtlAnsiStringToUnicodeString(&SrcFileName, &AnsiString, TRUE);
  125. if (!NT_SUCCESS(Status)) {
  126. SetLastError(Status);
  127. return VIF_OUTOFMEMORY;
  128. }
  129. RtlInitAnsiString(&AnsiString, lpszDstFileName);
  130. Status = RtlAnsiStringToUnicodeString(&DstFileName, &AnsiString, TRUE);
  131. if (!NT_SUCCESS(Status)) {
  132. RtlFreeUnicodeString(&SrcFileName);
  133. SetLastError(Status);
  134. return VIF_OUTOFMEMORY;
  135. }
  136. RtlInitAnsiString(&AnsiString, lpszSrcDir);
  137. Status = RtlAnsiStringToUnicodeString(&SrcDir, &AnsiString, TRUE);
  138. if (!NT_SUCCESS(Status)) {
  139. RtlFreeUnicodeString(&SrcFileName);
  140. RtlFreeUnicodeString(&DstFileName);
  141. SetLastError(Status);
  142. return VIF_OUTOFMEMORY;
  143. }
  144. RtlInitAnsiString(&AnsiString, lpszCurDir);
  145. Status = RtlAnsiStringToUnicodeString(&CurDir, &AnsiString, TRUE);
  146. if (!NT_SUCCESS(Status)) {
  147. RtlFreeUnicodeString(&SrcFileName);
  148. RtlFreeUnicodeString(&DstFileName);
  149. RtlFreeUnicodeString(&SrcDir);
  150. SetLastError(Status);
  151. return VIF_OUTOFMEMORY;
  152. }
  153. RtlInitAnsiString(&AnsiString, lpszDstDir);
  154. Status = RtlAnsiStringToUnicodeString(&DstDir, &AnsiString, TRUE);
  155. if (!NT_SUCCESS(Status)) {
  156. RtlFreeUnicodeString(&SrcFileName);
  157. RtlFreeUnicodeString(&DstFileName);
  158. RtlFreeUnicodeString(&SrcDir);
  159. RtlFreeUnicodeString(&CurDir);
  160. SetLastError(Status);
  161. return VIF_OUTOFMEMORY;
  162. }
  163. RtlInitAnsiString(&AnsiString, lpszTmpFile);
  164. TmpFile.MaximumLength = (USHORT)(TmpFileLen * sizeof(WCHAR));
  165. TmpFile.Buffer = RtlAllocateHeap(RtlProcessHeap(), 0, TmpFile.MaximumLength);
  166. if (TmpFile.Buffer == NULL) {
  167. RtlFreeUnicodeString(&SrcFileName);
  168. RtlFreeUnicodeString(&DstFileName);
  169. RtlFreeUnicodeString(&SrcDir);
  170. RtlFreeUnicodeString(&CurDir);
  171. RtlFreeUnicodeString(&DstDir);
  172. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  173. return VIF_OUTOFMEMORY;
  174. }
  175. Status = RtlAnsiStringToUnicodeString(&TmpFile, &AnsiString, FALSE);
  176. if (!NT_SUCCESS(Status)) {
  177. RtlFreeUnicodeString(&SrcFileName);
  178. RtlFreeUnicodeString(&DstFileName);
  179. RtlFreeUnicodeString(&SrcDir);
  180. RtlFreeUnicodeString(&CurDir);
  181. RtlFreeUnicodeString(&DstDir);
  182. RtlFreeUnicodeString(&TmpFile);
  183. SetLastError(Status);
  184. return VIF_OUTOFMEMORY;
  185. }
  186. Status = VerInstallFileW(wFlags,
  187. SrcFileName.Buffer,
  188. DstFileName.Buffer,
  189. SrcDir.Buffer,
  190. DstDir.Buffer,
  191. CurDir.Buffer,
  192. TmpFile.Buffer, &TmpFileLen);
  193. if (Status & VIF_BUFFTOOSMALL) {
  194. //
  195. // The lpszTmpFile buffer was too small,
  196. // the TmpFileLen field contains the size necessary.
  197. //
  198. *lpszTmpFile = 0;
  199. *puTmpFileLen = TmpFileLen;
  200. } else {
  201. TmpFile.Length = TmpFile.MaximumLength = (USHORT)(TmpFileLen * sizeof(WCHAR));
  202. AnsiString.Buffer = lpszTmpFile;
  203. AnsiString.MaximumLength = (USHORT)*puTmpFileLen;
  204. RtlUnicodeStringToAnsiString(&AnsiString, &TmpFile, FALSE);
  205. *puTmpFileLen = AnsiString.Length;
  206. }
  207. RtlFreeUnicodeString(&SrcFileName);
  208. RtlFreeUnicodeString(&DstFileName);
  209. RtlFreeUnicodeString(&SrcDir);
  210. RtlFreeUnicodeString(&DstDir);
  211. RtlFreeUnicodeString(&CurDir);
  212. RtlFreeUnicodeString(&TmpFile);
  213. return Status;
  214. }
  215. DWORD
  216. APIENTRY
  217. GetFileVersionInfoSizeA(
  218. LPCSTR lpstrFilename,
  219. LPDWORD lpdwHandle
  220. )
  221. {
  222. UNICODE_STRING FileName;
  223. ANSI_STRING AnsiString;
  224. NTSTATUS Status;
  225. DWORD dwStatus;
  226. RtlInitAnsiString(&AnsiString, lpstrFilename);
  227. Status = RtlAnsiStringToUnicodeString(&FileName, &AnsiString, TRUE);
  228. if (!NT_SUCCESS(Status)) {
  229. SetLastError(Status);
  230. return FALSE;
  231. }
  232. dwStatus = GetFileVersionInfoSizeW(FileName.Buffer, lpdwHandle);
  233. RtlFreeUnicodeString(&FileName);
  234. return dwStatus;
  235. }
  236. BOOL
  237. APIENTRY
  238. GetFileVersionInfoA(
  239. LPCSTR lpstrFilename,
  240. DWORD dwHandle,
  241. DWORD dwLen,
  242. LPVOID lpData
  243. )
  244. {
  245. UNICODE_STRING FileName;
  246. ANSI_STRING AnsiString;
  247. NTSTATUS Status;
  248. BOOL bStatus;
  249. RtlInitAnsiString(&AnsiString, lpstrFilename);
  250. Status = RtlAnsiStringToUnicodeString(&FileName, &AnsiString, TRUE);
  251. if (!NT_SUCCESS(Status)) {
  252. SetLastError(Status);
  253. return FALSE;
  254. }
  255. bStatus = GetFileVersionInfoW(FileName.Buffer, dwHandle, dwLen, lpData);
  256. RtlFreeUnicodeString(&FileName);
  257. return bStatus;
  258. }
  259. /*
  260. * DWORD
  261. * APIENTRY
  262. * VerLanguageNameA(
  263. * DWORD wLang,
  264. * LPSTR szLang,
  265. * DWORD wSize)
  266. *
  267. * This routine was moved to NLSLIB.LIB so that it uses the WINNLS.RC file.
  268. * NLSLIB.LIB is part of KERNEL32.DLL.
  269. */
  270. BOOL
  271. APIENTRY
  272. VerQueryValueIndexA(
  273. const LPVOID pb,
  274. LPSTR lpSubBlock,
  275. INT nIndex,
  276. LPVOID *lplpKey,
  277. LPVOID *lplpBuffer,
  278. PUINT puLen
  279. )
  280. {
  281. return VerpQueryValue(pb,
  282. lpSubBlock,
  283. nIndex,
  284. lplpKey,
  285. lplpBuffer,
  286. puLen,
  287. FALSE);
  288. }
  289. BOOL
  290. APIENTRY
  291. VerQueryValueA(
  292. const LPVOID pb,
  293. LPSTR lpSubBlock,
  294. LPVOID *lplpBuffer,
  295. PUINT puLen
  296. )
  297. {
  298. return VerpQueryValue(pb,
  299. lpSubBlock,
  300. -1,
  301. NULL,
  302. lplpBuffer,
  303. puLen,
  304. FALSE);
  305. }
  306. BOOL
  307. APIENTRY
  308. VerQueryValueW(
  309. const LPVOID pb,
  310. LPWSTR lpSubBlock,
  311. LPVOID *lplpBuffer,
  312. PUINT puLen
  313. )
  314. {
  315. return VerpQueryValue(pb,
  316. lpSubBlock,
  317. -1,
  318. NULL,
  319. lplpBuffer,
  320. puLen,
  321. TRUE);
  322. }
  323. BOOL
  324. APIENTRY
  325. VerQueryValueIndexW(
  326. const LPVOID pb,
  327. LPWSTR lpSubBlock,
  328. INT nIndex,
  329. LPVOID *lplpKey,
  330. LPVOID *lplpBuffer,
  331. PUINT puLen
  332. )
  333. {
  334. return VerpQueryValue(pb,
  335. lpSubBlock,
  336. nIndex,
  337. lplpKey,
  338. lplpBuffer,
  339. puLen,
  340. TRUE);
  341. }
  342.