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.

644 lines
13 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. lcompat.c
  5. Abstract:
  6. This module implements the _l and l compatability functions
  7. like _lread, lstrlen...
  8. Author:
  9. Mark Lucovsky (markl) 13-Mar-1991
  10. Revision History:
  11. --*/
  12. #include "basedll.h"
  13. int
  14. WINAPI
  15. _lopen(
  16. LPCSTR lpPathName,
  17. int iReadWrite
  18. )
  19. {
  20. HANDLE hFile;
  21. DWORD DesiredAccess;
  22. DWORD ShareMode;
  23. DWORD CreateDisposition;
  24. SetLastError(0);
  25. //
  26. // Compute Desired Access
  27. //
  28. if ( iReadWrite & OF_WRITE ) {
  29. DesiredAccess = GENERIC_WRITE;
  30. } else {
  31. DesiredAccess = GENERIC_READ;
  32. }
  33. if ( iReadWrite & OF_READWRITE ) {
  34. DesiredAccess |= (GENERIC_READ | GENERIC_WRITE);
  35. }
  36. //
  37. // Compute ShareMode
  38. //
  39. ShareMode = BasepOfShareToWin32Share ((DWORD)iReadWrite);
  40. CreateDisposition = OPEN_EXISTING;
  41. //
  42. // Open the file
  43. //
  44. hFile = CreateFile (lpPathName,
  45. DesiredAccess,
  46. ShareMode,
  47. NULL,
  48. CreateDisposition,
  49. 0,
  50. NULL);
  51. return (HFILE)HandleToUlong (hFile);
  52. }
  53. HFILE
  54. WINAPI
  55. _lcreat(
  56. LPCSTR lpPathName,
  57. int iAttribute
  58. )
  59. {
  60. HANDLE hFile;
  61. DWORD DesiredAccess;
  62. DWORD ShareMode;
  63. DWORD CreateDisposition;
  64. SetLastError(0);
  65. //
  66. // Compute Desired Access
  67. //
  68. DesiredAccess = (GENERIC_READ | GENERIC_WRITE);
  69. ShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;;
  70. //
  71. // Compute Create Disposition
  72. //
  73. CreateDisposition = CREATE_ALWAYS;
  74. //
  75. // Open the file
  76. //
  77. hFile = CreateFile (lpPathName,
  78. DesiredAccess,
  79. ShareMode,
  80. NULL,
  81. CreateDisposition,
  82. iAttribute & FILE_ATTRIBUTE_VALID_FLAGS,
  83. NULL);
  84. return (HFILE)HandleToUlong (hFile);
  85. }
  86. UINT
  87. WINAPI
  88. _lread(
  89. HFILE hFile,
  90. LPVOID lpBuffer,
  91. UINT uBytes
  92. )
  93. {
  94. DWORD BytesRead;
  95. BOOL b;
  96. b = ReadFile ((HANDLE)IntToPtr (hFile),
  97. lpBuffer,
  98. (DWORD)uBytes,
  99. &BytesRead,
  100. NULL);
  101. if (b) {
  102. return BytesRead;
  103. } else {
  104. return (DWORD)0xffffffff;
  105. }
  106. }
  107. UINT
  108. WINAPI
  109. _lwrite(
  110. HFILE hFile,
  111. LPCSTR lpBuffer,
  112. UINT uBytes
  113. )
  114. {
  115. DWORD BytesWritten;
  116. BOOL b;
  117. if (uBytes) {
  118. b = WriteFile ((HANDLE)IntToPtr(hFile),
  119. (CONST VOID *)lpBuffer,
  120. (DWORD)uBytes,
  121. &BytesWritten,
  122. NULL);
  123. } else {
  124. BytesWritten = 0;
  125. b = SetEndOfFile((HANDLE)IntToPtr(hFile));
  126. }
  127. if (b) {
  128. return BytesWritten;
  129. } else {
  130. return (DWORD)0xffffffff;
  131. }
  132. }
  133. HFILE
  134. WINAPI
  135. _lclose(
  136. HFILE hFile
  137. )
  138. {
  139. BOOL b;
  140. b = CloseHandle ((HANDLE)IntToPtr (hFile));
  141. if (b) {
  142. return (HFILE)0;
  143. } else {
  144. return (HFILE)-1;
  145. }
  146. }
  147. LONG
  148. WINAPI
  149. _llseek(
  150. HFILE hFile,
  151. LONG lOffset,
  152. int iOrigin
  153. )
  154. {
  155. DWORD SeekType;
  156. switch (iOrigin) {
  157. case 0:
  158. SeekType = FILE_BEGIN;
  159. break;
  160. case 1:
  161. SeekType = FILE_CURRENT;
  162. break;
  163. case 2:
  164. SeekType = FILE_END;
  165. break;
  166. default:
  167. return -1;
  168. }
  169. return (int)SetFilePointer ((HANDLE)IntToPtr (hFile), lOffset, NULL, SeekType);
  170. }
  171. #if defined(_AMD64_) || defined(_IA64_)
  172. int
  173. WINAPI
  174. MulDiv (
  175. int nNumber,
  176. int nNumerator,
  177. int nDenominator
  178. )
  179. {
  180. LONG Negate;
  181. union {
  182. LARGE_INTEGER Product;
  183. struct {
  184. ULONG Quotient;
  185. ULONG Remainder;
  186. };
  187. } u;
  188. //
  189. // Compute the size of the result.
  190. //
  191. Negate = nNumber ^ nNumerator ^ nDenominator;
  192. //
  193. // Get the absolute value of the operand values.
  194. //
  195. if (nNumber < 0) {
  196. nNumber = - nNumber;
  197. }
  198. if (nNumerator < 0) {
  199. nNumerator = - nNumerator;
  200. }
  201. if (nDenominator < 0) {
  202. nDenominator = - nDenominator;
  203. }
  204. //
  205. // Compute the 64-bit product of the multiplier and multiplicand
  206. // values and round.
  207. //
  208. u.Product.QuadPart =
  209. Int32x32To64(nNumber, nNumerator) + ((ULONG)nDenominator / 2);
  210. //
  211. // If there are any high order product bits, then the quotient has
  212. // overflowed.
  213. //
  214. if ((ULONG)nDenominator > u.Remainder) {
  215. //
  216. // Divide the 64-bit product by the 32-bit divisor forming a 32-bit
  217. // quotient and a 32-bit remainder.
  218. //
  219. u.Quotient = RtlEnlargedUnsignedDivide(*(PULARGE_INTEGER)&u.Product,
  220. (ULONG)nDenominator,
  221. &u.Remainder);
  222. //
  223. // Compute the final signed result.
  224. //
  225. if ((LONG)u.Quotient >= 0) {
  226. if (Negate >= 0) {
  227. return (LONG)u.Quotient;
  228. } else {
  229. return - (LONG)u.Quotient;
  230. }
  231. }
  232. }
  233. return - 1;
  234. }
  235. #endif
  236. int
  237. APIENTRY
  238. lstrcmpA(
  239. LPCSTR lpString1,
  240. LPCSTR lpString2
  241. )
  242. {
  243. int retval;
  244. retval = CompareStringA( GetThreadLocale(),
  245. LOCALE_USE_CP_ACP,
  246. lpString1,
  247. -1,
  248. lpString2,
  249. -1 );
  250. if (retval == 0) {
  251. //
  252. // The caller is not expecting failure. Try the system
  253. // default locale id.
  254. //
  255. retval = CompareStringA( GetSystemDefaultLCID(),
  256. LOCALE_USE_CP_ACP,
  257. lpString1,
  258. -1,
  259. lpString2,
  260. -1 );
  261. }
  262. if (retval == 0) {
  263. if (lpString1 && lpString2) {
  264. //
  265. // The caller is not expecting failure. We've never had a
  266. // failure indicator before. We'll do a best guess by calling
  267. // the C runtimes to do a non-locale sensitive compare.
  268. //
  269. return strcmp(lpString1, lpString2);
  270. } else if (lpString1) {
  271. return (1);
  272. } else if (lpString2) {
  273. return (-1);
  274. } else {
  275. return (0);
  276. }
  277. }
  278. return (retval - 2);
  279. }
  280. int
  281. APIENTRY
  282. lstrcmpiA(
  283. LPCSTR lpString1,
  284. LPCSTR lpString2
  285. )
  286. {
  287. int retval;
  288. retval = CompareStringA( GetThreadLocale(),
  289. LOCALE_USE_CP_ACP | NORM_IGNORECASE,
  290. lpString1,
  291. -1,
  292. lpString2,
  293. -1 );
  294. if (retval == 0) {
  295. //
  296. // The caller is not expecting failure. Try the system
  297. // default locale id.
  298. //
  299. retval = CompareStringA( GetSystemDefaultLCID(),
  300. LOCALE_USE_CP_ACP | NORM_IGNORECASE,
  301. lpString1,
  302. -1,
  303. lpString2,
  304. -1 );
  305. }
  306. if (retval == 0) {
  307. if (lpString1 && lpString2) {
  308. //
  309. // The caller is not expecting failure. We've never had a
  310. // failure indicator before. We'll do a best guess by calling
  311. // the C runtimes to do a non-locale sensitive compare.
  312. //
  313. return ( _stricmp(lpString1, lpString2) );
  314. } else if (lpString1) {
  315. return (1);
  316. } else if (lpString2) {
  317. return (-1);
  318. } else {
  319. return (0);
  320. }
  321. }
  322. return (retval - 2);
  323. }
  324. LPSTR
  325. APIENTRY
  326. lstrcpyA(
  327. LPSTR lpString1,
  328. LPCSTR lpString2
  329. )
  330. {
  331. try {
  332. return strcpy (lpString1, lpString2);
  333. } except (EXCEPTION_EXECUTE_HANDLER) {
  334. return NULL;
  335. }
  336. }
  337. LPSTR
  338. APIENTRY
  339. lstrcpynA(
  340. LPSTR lpString1,
  341. LPCSTR lpString2,
  342. int iMaxLength
  343. )
  344. {
  345. LPSTR src,dst;
  346. try {
  347. src = (LPSTR)lpString2;
  348. dst = lpString1;
  349. if ( iMaxLength ) {
  350. while(iMaxLength && *src){
  351. *dst++ = *src++;
  352. iMaxLength--;
  353. }
  354. if ( iMaxLength ) {
  355. *dst = '\0';
  356. } else {
  357. dst--;
  358. *dst = '\0';
  359. }
  360. }
  361. } except (EXCEPTION_EXECUTE_HANDLER) {
  362. return NULL;
  363. }
  364. return lpString1;
  365. }
  366. LPSTR
  367. APIENTRY
  368. lstrcatA(
  369. LPSTR lpString1,
  370. LPCSTR lpString2
  371. )
  372. {
  373. try {
  374. return strcat (lpString1, lpString2);
  375. } except (EXCEPTION_EXECUTE_HANDLER) {
  376. return NULL;
  377. }
  378. }
  379. int
  380. APIENTRY
  381. lstrlenA(
  382. LPCSTR lpString
  383. )
  384. {
  385. if (!lpString) {
  386. return 0;
  387. }
  388. try {
  389. return strlen(lpString);
  390. } except (EXCEPTION_EXECUTE_HANDLER) {
  391. return 0;
  392. }
  393. }
  394. int
  395. APIENTRY
  396. lstrcmpW(
  397. LPCWSTR lpString1,
  398. LPCWSTR lpString2
  399. )
  400. {
  401. int retval;
  402. retval = CompareStringW( GetThreadLocale(),
  403. 0,
  404. lpString1,
  405. -1,
  406. lpString2,
  407. -1 );
  408. if (retval == 0) {
  409. //
  410. // The caller is not expecting failure. Try the system
  411. // default locale id.
  412. //
  413. retval = CompareStringW( GetSystemDefaultLCID(),
  414. 0,
  415. lpString1,
  416. -1,
  417. lpString2,
  418. -1 );
  419. }
  420. if (retval == 0) {
  421. if (lpString1 && lpString2) {
  422. //
  423. // The caller is not expecting failure. We've never had a
  424. // failure indicator before. We'll do a best guess by calling
  425. // the C runtimes to do a non-locale sensitive compare.
  426. //
  427. return ( wcscmp(lpString1, lpString2) );
  428. } else if (lpString1) {
  429. return (1);
  430. } else if (lpString2) {
  431. return (-1);
  432. } else {
  433. return (0);
  434. }
  435. }
  436. return (retval - 2);
  437. }
  438. int
  439. APIENTRY
  440. lstrcmpiW(
  441. LPCWSTR lpString1,
  442. LPCWSTR lpString2
  443. )
  444. {
  445. int retval;
  446. retval = CompareStringW( GetThreadLocale(),
  447. NORM_IGNORECASE,
  448. lpString1,
  449. -1,
  450. lpString2,
  451. -1 );
  452. if (retval == 0) {
  453. //
  454. // The caller is not expecting failure. Try the system
  455. // default locale id.
  456. //
  457. retval = CompareStringW( GetSystemDefaultLCID(),
  458. NORM_IGNORECASE,
  459. lpString1,
  460. -1,
  461. lpString2,
  462. -1 );
  463. }
  464. if (retval == 0) {
  465. if (lpString1 && lpString2) {
  466. //
  467. // The caller is not expecting failure. We've never had a
  468. // failure indicator before. We'll do a best guess by calling
  469. // the C runtimes to do a non-locale sensitive compare.
  470. //
  471. return ( _wcsicmp(lpString1, lpString2) );
  472. } else if (lpString1) {
  473. return (1);
  474. } else if (lpString2) {
  475. return (-1);
  476. } else {
  477. return (0);
  478. }
  479. }
  480. return (retval - 2);
  481. }
  482. LPWSTR
  483. APIENTRY
  484. lstrcpyW(
  485. LPWSTR lpString1,
  486. LPCWSTR lpString2
  487. )
  488. {
  489. try {
  490. return wcscpy (lpString1, lpString2);
  491. } except (EXCEPTION_EXECUTE_HANDLER) {
  492. return NULL;
  493. }
  494. }
  495. LPWSTR
  496. APIENTRY
  497. lstrcpynW(
  498. LPWSTR lpString1,
  499. LPCWSTR lpString2,
  500. int iMaxLength
  501. )
  502. {
  503. LPWSTR src,dst;
  504. try {
  505. src = (LPWSTR)lpString2;
  506. dst = lpString1;
  507. if ( iMaxLength ) {
  508. while(iMaxLength && *src){
  509. *dst++ = *src++;
  510. iMaxLength--;
  511. }
  512. if ( iMaxLength ) {
  513. *dst = '\0';
  514. } else {
  515. dst--;
  516. *dst = '\0';
  517. }
  518. }
  519. } except (EXCEPTION_EXECUTE_HANDLER) {
  520. return NULL;
  521. }
  522. return lpString1;
  523. }
  524. LPWSTR
  525. APIENTRY
  526. lstrcatW(
  527. LPWSTR lpString1,
  528. LPCWSTR lpString2
  529. )
  530. {
  531. try {
  532. return wcscat (lpString1, lpString2);
  533. } except (EXCEPTION_EXECUTE_HANDLER) {
  534. return NULL;
  535. }
  536. }
  537. int
  538. APIENTRY
  539. lstrlenW(
  540. LPCWSTR lpString
  541. )
  542. {
  543. if (!lpString) {
  544. return 0;
  545. }
  546. try {
  547. return wcslen (lpString);
  548. } except (EXCEPTION_EXECUTE_HANDLER) {
  549. return 0;
  550. }
  551. }