windows-nt/Source/XPSP1/NT/base/win32/client/lcompat.c
2020-09-26 16:20:57 +08:00

687 lines
13 KiB
C

/*++
Copyright (c) 1990 Microsoft Corporation
Module Name:
lcompat.c
Abstract:
This module implements the _l and l compatability functions
like _lread, lstrlen...
Author:
Mark Lucovsky (markl) 13-Mar-1991
Revision History:
--*/
#include "basedll.h"
int
WINAPI
_lopen(
LPCSTR lpPathName,
int iReadWrite
)
{
HANDLE hFile;
DWORD DesiredAccess;
DWORD ShareMode;
DWORD CreateDisposition;
SetLastError(0);
//
// Compute Desired Access
//
if ( iReadWrite & OF_WRITE ) {
DesiredAccess = GENERIC_WRITE;
}
else {
DesiredAccess = GENERIC_READ;
}
if ( iReadWrite & OF_READWRITE ) {
DesiredAccess |= (GENERIC_READ | GENERIC_WRITE);
}
//
// Compute ShareMode
//
ShareMode = BasepOfShareToWin32Share((DWORD)iReadWrite);
CreateDisposition = OPEN_EXISTING;
//
// Open the file
//
hFile = CreateFile(
lpPathName,
DesiredAccess,
ShareMode,
NULL,
CreateDisposition,
0,
NULL
);
return (HFILE)HandleToUlong(hFile);
}
HFILE
WINAPI
_lcreat(
LPCSTR lpPathName,
int iAttribute
)
{
HANDLE hFile;
DWORD DesiredAccess;
DWORD ShareMode;
DWORD CreateDisposition;
SetLastError(0);
//
// Compute Desired Access
//
DesiredAccess = (GENERIC_READ | GENERIC_WRITE);
ShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;;
//
// Compute Create Disposition
//
CreateDisposition = CREATE_ALWAYS;
//
// Open the file
//
hFile = CreateFile(
lpPathName,
DesiredAccess,
ShareMode,
NULL,
CreateDisposition,
iAttribute & FILE_ATTRIBUTE_VALID_FLAGS,
NULL
);
return (HFILE)HandleToUlong(hFile);
}
UINT
WINAPI
_lread(
HFILE hFile,
LPVOID lpBuffer,
UINT uBytes
)
{
DWORD BytesRead;
BOOL b;
b = ReadFile((HANDLE)IntToPtr(hFile),lpBuffer,(DWORD)uBytes,&BytesRead,NULL);
if ( b ) {
return BytesRead;
}
else {
return (DWORD)0xffffffff;
}
}
UINT
WINAPI
_lwrite(
HFILE hFile,
LPCSTR lpBuffer,
UINT uBytes
)
{
DWORD BytesWritten;
BOOL b;
if ( uBytes ) {
b = WriteFile((HANDLE)IntToPtr(hFile),(CONST VOID *)lpBuffer,(DWORD)uBytes,&BytesWritten,NULL);
}
else {
BytesWritten = 0;
b = SetEndOfFile((HANDLE)IntToPtr(hFile));
}
if ( b ) {
return BytesWritten;
}
else {
return (DWORD)0xffffffff;
}
}
HFILE
WINAPI
_lclose(
HFILE hFile
)
{
BOOL b;
b = CloseHandle((HANDLE)IntToPtr(hFile));
if ( b ) {
return (HFILE)0;
}
else {
return (HFILE)-1;
}
}
LONG
WINAPI
_llseek(
HFILE hFile,
LONG lOffset,
int iOrigin
)
{
DWORD SeekType;
switch ( iOrigin ) {
case 0:
SeekType = FILE_BEGIN;
break;
case 1:
SeekType = FILE_CURRENT;
break;
case 2:
SeekType = FILE_END;
break;
default:
return -1;
}
return (int)SetFilePointer((HANDLE)IntToPtr(hFile), lOffset, NULL, SeekType);
}
#if defined(_AMD64_) || defined(_IA64_)
int
WINAPI
MulDiv (
int nNumber,
int nNumerator,
int nDenominator
)
{
LONG Negate;
union {
LARGE_INTEGER Product;
struct {
ULONG Quotient;
ULONG Remainder;
};
} u;
//
// Compute the size of the result.
//
Negate = nNumber ^ nNumerator ^ nDenominator;
//
// Get the absolute value of the operand values.
//
if (nNumber < 0) {
nNumber = - nNumber;
}
if (nNumerator < 0) {
nNumerator = - nNumerator;
}
if (nDenominator < 0) {
nDenominator = - nDenominator;
}
//
// Compute the 64-bit product of the multiplier and multiplicand
// values and round.
//
u.Product.QuadPart =
Int32x32To64(nNumber, nNumerator) + ((ULONG)nDenominator / 2);
//
// If there are any high order product bits, then the quotient has
// overflowed.
//
if ((ULONG)nDenominator > u.Remainder) {
//
// Divide the 64-bit product by the 32-bit divisor forming a 32-bit
// quotient and a 32-bit remainder.
//
u.Quotient = RtlEnlargedUnsignedDivide(*(PULARGE_INTEGER)&u.Product,
(ULONG)nDenominator,
&u.Remainder);
//
// Compute the final signed result.
//
if ((LONG)u.Quotient >= 0) {
if (Negate >= 0) {
return (LONG)u.Quotient;
} else {
return - (LONG)u.Quotient;
}
}
}
return - 1;
}
#endif
int
APIENTRY
lstrcmpA(
LPCSTR lpString1,
LPCSTR lpString2
)
{
int retval;
retval = CompareStringA( GetThreadLocale(),
LOCALE_USE_CP_ACP,
lpString1,
-1,
lpString2,
-1 );
if (retval == 0)
{
//
// The caller is not expecting failure. Try the system
// default locale id.
//
retval = CompareStringA( GetSystemDefaultLCID(),
LOCALE_USE_CP_ACP,
lpString1,
-1,
lpString2,
-1 );
}
if (retval == 0)
{
if (lpString1 && lpString2)
{
//
// The caller is not expecting failure. We've never had a
// failure indicator before. We'll do a best guess by calling
// the C runtimes to do a non-locale sensitive compare.
//
return strcmp(lpString1, lpString2);
}
else if (lpString1)
{
return (1);
}
else if (lpString2)
{
return (-1);
}
else
{
return (0);
}
}
return (retval - 2);
}
int
APIENTRY
lstrcmpiA(
LPCSTR lpString1,
LPCSTR lpString2
)
{
int retval;
retval = CompareStringA( GetThreadLocale(),
LOCALE_USE_CP_ACP | NORM_IGNORECASE,
lpString1,
-1,
lpString2,
-1 );
if (retval == 0)
{
//
// The caller is not expecting failure. Try the system
// default locale id.
//
retval = CompareStringA( GetSystemDefaultLCID(),
LOCALE_USE_CP_ACP | NORM_IGNORECASE,
lpString1,
-1,
lpString2,
-1 );
}
if (retval == 0)
{
if (lpString1 && lpString2)
{
//
// The caller is not expecting failure. We've never had a
// failure indicator before. We'll do a best guess by calling
// the C runtimes to do a non-locale sensitive compare.
//
return ( _stricmp(lpString1, lpString2) );
}
else if (lpString1)
{
return (1);
}
else if (lpString2)
{
return (-1);
}
else
{
return (0);
}
}
return (retval - 2);
}
LPSTR
APIENTRY
lstrcpyA(
LPSTR lpString1,
LPCSTR lpString2
)
{
__try {
return strcpy(lpString1, lpString2);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
return NULL;
}
}
LPSTR
APIENTRY
lstrcpynA(
LPSTR lpString1,
LPCSTR lpString2,
int iMaxLength
)
{
LPSTR src,dst;
__try {
src = (LPSTR)lpString2;
dst = lpString1;
if ( iMaxLength ) {
while(iMaxLength && *src){
*dst++ = *src++;
iMaxLength--;
}
if ( iMaxLength ) {
*dst = '\0';
}
else {
dst--;
*dst = '\0';
}
}
}
__except (EXCEPTION_EXECUTE_HANDLER) {
return NULL;
}
return lpString1;
}
LPSTR
APIENTRY
lstrcatA(
LPSTR lpString1,
LPCSTR lpString2
)
{
__try {
return strcat(lpString1, lpString2);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
return NULL;
}
}
int
APIENTRY
lstrlenA(
LPCSTR lpString
)
{
if (!lpString)
return 0;
__try {
return strlen(lpString);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
return 0;
}
}
int
APIENTRY
lstrcmpW(
LPCWSTR lpString1,
LPCWSTR lpString2
)
{
int retval;
retval = CompareStringW( GetThreadLocale(),
0,
lpString1,
-1,
lpString2,
-1 );
if (retval == 0)
{
//
// The caller is not expecting failure. Try the system
// default locale id.
//
retval = CompareStringW( GetSystemDefaultLCID(),
0,
lpString1,
-1,
lpString2,
-1 );
}
if (retval == 0)
{
if (lpString1 && lpString2)
{
//
// The caller is not expecting failure. We've never had a
// failure indicator before. We'll do a best guess by calling
// the C runtimes to do a non-locale sensitive compare.
//
return ( wcscmp(lpString1, lpString2) );
}
else if (lpString1)
{
return (1);
}
else if (lpString2)
{
return (-1);
}
else
{
return (0);
}
}
return (retval - 2);
}
int
APIENTRY
lstrcmpiW(
LPCWSTR lpString1,
LPCWSTR lpString2
)
{
int retval;
retval = CompareStringW( GetThreadLocale(),
NORM_IGNORECASE,
lpString1,
-1,
lpString2,
-1 );
if (retval == 0)
{
//
// The caller is not expecting failure. Try the system
// default locale id.
//
retval = CompareStringW( GetSystemDefaultLCID(),
NORM_IGNORECASE,
lpString1,
-1,
lpString2,
-1 );
}
if (retval == 0)
{
if (lpString1 && lpString2)
{
//
// The caller is not expecting failure. We've never had a
// failure indicator before. We'll do a best guess by calling
// the C runtimes to do a non-locale sensitive compare.
//
return ( _wcsicmp(lpString1, lpString2) );
}
else if (lpString1)
{
return (1);
}
else if (lpString2)
{
return (-1);
}
else
{
return (0);
}
}
return (retval - 2);
}
LPWSTR
APIENTRY
lstrcpyW(
LPWSTR lpString1,
LPCWSTR lpString2
)
{
__try {
return wcscpy(lpString1, lpString2);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
return NULL;
}
}
LPWSTR
APIENTRY
lstrcpynW(
LPWSTR lpString1,
LPCWSTR lpString2,
int iMaxLength
)
{
LPWSTR src,dst;
__try {
src = (LPWSTR)lpString2;
dst = lpString1;
if ( iMaxLength ) {
while(iMaxLength && *src){
*dst++ = *src++;
iMaxLength--;
}
if ( iMaxLength ) {
*dst = '\0';
}
else {
dst--;
*dst = '\0';
}
}
}
__except (EXCEPTION_EXECUTE_HANDLER) {
return NULL;
}
return lpString1;
}
LPWSTR
APIENTRY
lstrcatW(
LPWSTR lpString1,
LPCWSTR lpString2
)
{
__try {
return wcscat(lpString1, lpString2);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
return NULL;
}
}
int
APIENTRY
lstrlenW(
LPCWSTR lpString
)
{
if (!lpString)
return 0;
__try {
return wcslen(lpString);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
return 0;
}
}