Source code of Windows XP (NT5)
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.

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