mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-08-26 19:33:31 +00:00
[KERNEL32] Split off some ANSI functions from the bulk of Kernel32 (#8555)
* [KERNEL32] Split off some ANSI functions from the bulk of Kernel32 Co-authored-by: Hermès BÉLUSCA - MAÏTO <[email protected]>
This commit is contained in:
co-authored by
Hermès BÉLUSCA - MAÏTO
parent
9ef0557de5
commit
c81bc9f21e
@@ -17,6 +17,7 @@ list(APPEND SOURCE
|
||||
client/actctx.c
|
||||
client/appcache.c
|
||||
client/atom.c
|
||||
client/atomansi.c
|
||||
client/compname.c
|
||||
client/debugger.c
|
||||
client/dosdev.c
|
||||
@@ -29,13 +30,17 @@ list(APPEND SOURCE
|
||||
client/job.c
|
||||
client/loader.c
|
||||
client/path.c
|
||||
client/pathansi.c
|
||||
client/perfcnt.c
|
||||
client/power.c
|
||||
client/proc.c
|
||||
client/procansi.c
|
||||
client/resntfy.c
|
||||
client/session.c
|
||||
client/synch.c
|
||||
client/synchansi.c
|
||||
client/sysinfo.c
|
||||
client/sysinfoansi.c
|
||||
client/time.c
|
||||
client/timerqueue.c
|
||||
client/toolhelp.c
|
||||
@@ -43,6 +48,7 @@ list(APPEND SOURCE
|
||||
client/thread.c
|
||||
client/vdm.c
|
||||
client/version.c
|
||||
client/versionansi.c
|
||||
client/virtmem.c
|
||||
client/console/alias.c
|
||||
client/console/console.c
|
||||
@@ -52,12 +58,15 @@ list(APPEND SOURCE
|
||||
client/file/backup.c
|
||||
client/file/cnotify.c
|
||||
client/file/copy.c
|
||||
client/file/copyansi.c
|
||||
client/file/create.c
|
||||
client/file/delete.c
|
||||
client/file/deviceio.c
|
||||
client/file/dir.c
|
||||
client/file/diransi.c
|
||||
client/file/disk.c
|
||||
client/file/fileinfo.c
|
||||
client/file/fileinfoansi.c
|
||||
client/file/filemap.c
|
||||
client/file/filename.c
|
||||
client/file/find.c
|
||||
@@ -67,11 +76,14 @@ list(APPEND SOURCE
|
||||
client/file/lock.c
|
||||
client/file/mailslot.c
|
||||
client/file/move.c
|
||||
client/file/moveansi.c
|
||||
client/file/mntpoint.c
|
||||
client/file/mntpointansi.c
|
||||
client/file/npipe.c
|
||||
client/file/rw.c
|
||||
client/file/tape.c
|
||||
client/file/volume.c
|
||||
client/file/volumeansi.c
|
||||
wine/actctx.c
|
||||
wine/comm.c
|
||||
wine/lzexpand.c
|
||||
@@ -86,7 +98,9 @@ list(APPEND SOURCE
|
||||
winnls/string/format_msg.c
|
||||
winnls/string/japanese.c
|
||||
winnls/string/locale.c
|
||||
winnls/string/localeansi.c
|
||||
winnls/string/lcformat.c
|
||||
winnls/string/lcformatansi.c
|
||||
winnls/string/lstring.c
|
||||
winnls/string/nls.c
|
||||
winnls/string/sortkey.c
|
||||
|
||||
@@ -426,16 +426,6 @@ InternalGetAtomName(BOOLEAN Local,
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
ATOM
|
||||
WINAPI
|
||||
GlobalAddAtomA(LPCSTR lpString)
|
||||
{
|
||||
return InternalAddAtom(FALSE, FALSE, lpString);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
@@ -456,16 +446,6 @@ GlobalDeleteAtom(ATOM nAtom)
|
||||
return InternalDeleteAtom(FALSE, nAtom);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
ATOM
|
||||
WINAPI
|
||||
GlobalFindAtomA(LPCSTR lpString)
|
||||
{
|
||||
return InternalFindAtom(FALSE, FALSE, lpString);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
* FILE: dll/win32/kernel32/client/atomansi.c
|
||||
* PURPOSE: Atom functions (ANSI)
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <k32.h>
|
||||
|
||||
/* Forward declarations from atom.c */
|
||||
ATOM WINAPI InternalAddAtom(BOOLEAN Local, BOOLEAN Unicode, LPCSTR AtomName);
|
||||
ATOM WINAPI InternalFindAtom(BOOLEAN Local, BOOLEAN Unicode, LPCSTR AtomName);
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
ATOM
|
||||
WINAPI
|
||||
GlobalAddAtomA(LPCSTR lpString)
|
||||
{
|
||||
return InternalAddAtom(FALSE, FALSE, lpString);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
ATOM
|
||||
WINAPI
|
||||
GlobalFindAtomA(LPCSTR lpString)
|
||||
{
|
||||
return InternalFindAtom(FALSE, FALSE, lpString);
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
@@ -357,80 +357,6 @@ CopyFileExW(IN LPCWSTR lpExistingFileName,
|
||||
return Ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
WINAPI
|
||||
CopyFileExA(IN LPCSTR lpExistingFileName,
|
||||
IN LPCSTR lpNewFileName,
|
||||
IN LPPROGRESS_ROUTINE lpProgressRoutine OPTIONAL,
|
||||
IN LPVOID lpData OPTIONAL,
|
||||
IN LPBOOL pbCancel OPTIONAL,
|
||||
IN DWORD dwCopyFlags)
|
||||
{
|
||||
BOOL Result = FALSE;
|
||||
UNICODE_STRING lpNewFileNameW;
|
||||
PUNICODE_STRING lpExistingFileNameW;
|
||||
|
||||
lpExistingFileNameW = Basep8BitStringToStaticUnicodeString(lpExistingFileName);
|
||||
if (!lpExistingFileNameW)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (Basep8BitStringToDynamicUnicodeString(&lpNewFileNameW, lpNewFileName))
|
||||
{
|
||||
Result = CopyFileExW(lpExistingFileNameW->Buffer,
|
||||
lpNewFileNameW.Buffer,
|
||||
lpProgressRoutine,
|
||||
lpData,
|
||||
pbCancel,
|
||||
dwCopyFlags);
|
||||
|
||||
RtlFreeUnicodeString(&lpNewFileNameW);
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
WINAPI
|
||||
CopyFileA(IN LPCSTR lpExistingFileName,
|
||||
IN LPCSTR lpNewFileName,
|
||||
IN BOOL bFailIfExists)
|
||||
{
|
||||
BOOL Result = FALSE;
|
||||
UNICODE_STRING lpNewFileNameW;
|
||||
PUNICODE_STRING lpExistingFileNameW;
|
||||
|
||||
lpExistingFileNameW = Basep8BitStringToStaticUnicodeString(lpExistingFileName);
|
||||
if (!lpExistingFileNameW)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (Basep8BitStringToDynamicUnicodeString(&lpNewFileNameW, lpNewFileName))
|
||||
{
|
||||
Result = CopyFileExW(lpExistingFileNameW->Buffer,
|
||||
lpNewFileNameW.Buffer,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
(bFailIfExists ? COPY_FILE_FAIL_IF_EXISTS : 0));
|
||||
|
||||
RtlFreeUnicodeString(&lpNewFileNameW);
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
* FILE: dll/win32/kernel32/client/file/copyansi.c
|
||||
* PURPOSE: Copying files
|
||||
* PROGRAMMER: Ariadne ([email protected])
|
||||
*/
|
||||
|
||||
/* INCLUDES ****************************************************************/
|
||||
|
||||
#include <k32.h>
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
WINAPI
|
||||
CopyFileExA(IN LPCSTR lpExistingFileName,
|
||||
IN LPCSTR lpNewFileName,
|
||||
IN LPPROGRESS_ROUTINE lpProgressRoutine OPTIONAL,
|
||||
IN LPVOID lpData OPTIONAL,
|
||||
IN LPBOOL pbCancel OPTIONAL,
|
||||
IN DWORD dwCopyFlags)
|
||||
{
|
||||
BOOL Result = FALSE;
|
||||
UNICODE_STRING lpNewFileNameW;
|
||||
PUNICODE_STRING lpExistingFileNameW;
|
||||
|
||||
lpExistingFileNameW = Basep8BitStringToStaticUnicodeString(lpExistingFileName);
|
||||
if (!lpExistingFileNameW)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (Basep8BitStringToDynamicUnicodeString(&lpNewFileNameW, lpNewFileName))
|
||||
{
|
||||
Result = CopyFileExW(lpExistingFileNameW->Buffer,
|
||||
lpNewFileNameW.Buffer,
|
||||
lpProgressRoutine,
|
||||
lpData,
|
||||
pbCancel,
|
||||
dwCopyFlags);
|
||||
|
||||
RtlFreeUnicodeString(&lpNewFileNameW);
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
WINAPI
|
||||
CopyFileA(IN LPCSTR lpExistingFileName,
|
||||
IN LPCSTR lpNewFileName,
|
||||
IN BOOL bFailIfExists)
|
||||
{
|
||||
BOOL Result = FALSE;
|
||||
UNICODE_STRING lpNewFileNameW;
|
||||
PUNICODE_STRING lpExistingFileNameW;
|
||||
|
||||
lpExistingFileNameW = Basep8BitStringToStaticUnicodeString(lpExistingFileName);
|
||||
if (!lpExistingFileNameW)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (Basep8BitStringToDynamicUnicodeString(&lpNewFileNameW, lpNewFileName))
|
||||
{
|
||||
Result = CopyFileExW(lpExistingFileNameW->Buffer,
|
||||
lpNewFileNameW.Buffer,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
(bFailIfExists ? COPY_FILE_FAIL_IF_EXISTS : 0));
|
||||
|
||||
RtlFreeUnicodeString(&lpNewFileNameW);
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
@@ -49,38 +49,6 @@ CreateDirectoryA(IN LPCSTR lpPathName,
|
||||
lpSecurityAttributes);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
WINAPI
|
||||
CreateDirectoryExA(IN LPCSTR lpTemplateDirectory,
|
||||
IN LPCSTR lpNewDirectory,
|
||||
IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
|
||||
{
|
||||
PUNICODE_STRING TemplateDirectoryW;
|
||||
UNICODE_STRING NewDirectoryW;
|
||||
BOOL ret;
|
||||
|
||||
TemplateDirectoryW = Basep8BitStringToStaticUnicodeString(lpTemplateDirectory);
|
||||
if (!TemplateDirectoryW)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!Basep8BitStringToDynamicUnicodeString(&NewDirectoryW, lpNewDirectory))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ret = CreateDirectoryExW(TemplateDirectoryW->Buffer,
|
||||
NewDirectoryW.Buffer,
|
||||
lpSecurityAttributes);
|
||||
|
||||
RtlFreeUnicodeString(&NewDirectoryW);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
* FILE: dll/win32/kernel32/client/file/diransi.c
|
||||
* PURPOSE: Directory functions
|
||||
* PROGRAMMER: Pierre Schweitzer ([email protected])
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <k32.h>
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
WINAPI
|
||||
CreateDirectoryExA(IN LPCSTR lpTemplateDirectory,
|
||||
IN LPCSTR lpNewDirectory,
|
||||
IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
|
||||
{
|
||||
PUNICODE_STRING TemplateDirectoryW;
|
||||
UNICODE_STRING NewDirectoryW;
|
||||
BOOL ret;
|
||||
|
||||
TemplateDirectoryW = Basep8BitStringToStaticUnicodeString(lpTemplateDirectory);
|
||||
if (!TemplateDirectoryW)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!Basep8BitStringToDynamicUnicodeString(&NewDirectoryW, lpNewDirectory))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ret = CreateDirectoryExW(TemplateDirectoryW->Buffer,
|
||||
NewDirectoryW.Buffer,
|
||||
lpSecurityAttributes);
|
||||
|
||||
RtlFreeUnicodeString(&NewDirectoryW);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
@@ -390,22 +390,6 @@ GetFileSizeEx(
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
DWORD WINAPI
|
||||
GetCompressedFileSizeA(LPCSTR lpFileName,
|
||||
LPDWORD lpFileSizeHigh)
|
||||
{
|
||||
PWCHAR FileNameW;
|
||||
|
||||
if (!(FileNameW = FilenameA2W(lpFileName, FALSE)))
|
||||
return INVALID_FILE_SIZE;
|
||||
|
||||
return GetCompressedFileSizeW(FileNameW, lpFileSizeHigh);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
* FILE: dll/win32/kernel32/client/file/fileinfo.c
|
||||
* PURPOSE: Directory functions
|
||||
* PROGRAMMER: Ariadne ( [email protected])
|
||||
* Pierre Schweitzer ([email protected])
|
||||
* UPDATE HISTORY:
|
||||
* Created 01/11/98
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <k32.h>
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
#if (NTDDI_VERSION < NTDDI_WINBLUE)
|
||||
/* moved to kernelbase in Windows 8.1 */
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
DWORD WINAPI
|
||||
GetCompressedFileSizeA(LPCSTR lpFileName,
|
||||
LPDWORD lpFileSizeHigh)
|
||||
{
|
||||
PWCHAR FileNameW;
|
||||
|
||||
if (!(FileNameW = FilenameA2W(lpFileName, FALSE)))
|
||||
return INVALID_FILE_SIZE;
|
||||
|
||||
return GetCompressedFileSizeW(FileNameW, lpFileSizeHigh);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* EOF */
|
||||
@@ -510,71 +510,6 @@ GetVolumeNameForVolumeMountPointW(IN LPCWSTR VolumeMountPoint,
|
||||
return Ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
WINAPI
|
||||
GetVolumeNameForVolumeMountPointA(IN LPCSTR lpszVolumeMountPoint,
|
||||
IN LPSTR lpszVolumeName,
|
||||
IN DWORD cchBufferLength)
|
||||
{
|
||||
BOOL Ret;
|
||||
ANSI_STRING VolumeName;
|
||||
UNICODE_STRING VolumeNameU;
|
||||
PUNICODE_STRING VolumeMountPointU;
|
||||
|
||||
/* Convert mount point to unicode */
|
||||
VolumeMountPointU = Basep8BitStringToStaticUnicodeString(lpszVolumeMountPoint);
|
||||
if (VolumeMountPointU == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Initialize the strings we'll use for convention */
|
||||
VolumeName.Buffer = lpszVolumeName;
|
||||
VolumeName.Length = 0;
|
||||
VolumeName.MaximumLength = cchBufferLength - 1;
|
||||
|
||||
VolumeNameU.Length = 0;
|
||||
VolumeNameU.MaximumLength = (cchBufferLength - 1) * sizeof(WCHAR) + sizeof(UNICODE_NULL);
|
||||
/* Allocate a buffer big enough to contain the returned name */
|
||||
VolumeNameU.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, VolumeNameU.MaximumLength);
|
||||
if (VolumeNameU.Buffer == NULL)
|
||||
{
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Query -W */
|
||||
Ret = GetVolumeNameForVolumeMountPointW(VolumeMountPointU->Buffer, VolumeNameU.Buffer, cchBufferLength);
|
||||
/* If it succeed, perform -A conversion */
|
||||
if (Ret)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
/* Reinit our string for length */
|
||||
RtlInitUnicodeString(&VolumeNameU, VolumeNameU.Buffer);
|
||||
/* Convert to ANSI */
|
||||
Status = RtlUnicodeStringToAnsiString(&VolumeName, &VolumeNameU, FALSE);
|
||||
/* If conversion failed, force failure, otherwise, just null terminate */
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
Ret = FALSE;
|
||||
BaseSetLastNTError(Status);
|
||||
}
|
||||
else
|
||||
{
|
||||
VolumeName.Buffer[VolumeName.Length] = ANSI_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Internal buffer no longer needed */
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeNameU.Buffer);
|
||||
|
||||
return Ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
* FILE: dll/win32/kernel32/client/file/mntpointansi.c
|
||||
* PURPOSE: Volume mount point functions (ANSI)
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <k32.h>
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
WINAPI
|
||||
GetVolumeNameForVolumeMountPointA(IN LPCSTR lpszVolumeMountPoint,
|
||||
IN LPSTR lpszVolumeName,
|
||||
IN DWORD cchBufferLength)
|
||||
{
|
||||
BOOL Ret;
|
||||
ANSI_STRING VolumeName;
|
||||
UNICODE_STRING VolumeNameU;
|
||||
PUNICODE_STRING VolumeMountPointU;
|
||||
|
||||
/* Convert mount point to unicode */
|
||||
VolumeMountPointU = Basep8BitStringToStaticUnicodeString(lpszVolumeMountPoint);
|
||||
if (VolumeMountPointU == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Initialize the strings we'll use for convention */
|
||||
VolumeName.Buffer = lpszVolumeName;
|
||||
VolumeName.Length = 0;
|
||||
VolumeName.MaximumLength = cchBufferLength - 1;
|
||||
|
||||
VolumeNameU.Length = 0;
|
||||
VolumeNameU.MaximumLength = (cchBufferLength - 1) * sizeof(WCHAR) + sizeof(UNICODE_NULL);
|
||||
/* Allocate a buffer big enough to contain the returned name */
|
||||
VolumeNameU.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, VolumeNameU.MaximumLength);
|
||||
if (VolumeNameU.Buffer == NULL)
|
||||
{
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Query -W */
|
||||
Ret = GetVolumeNameForVolumeMountPointW(VolumeMountPointU->Buffer, VolumeNameU.Buffer, cchBufferLength);
|
||||
/* If it succeed, perform -A conversion */
|
||||
if (Ret)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
/* Reinit our string for length */
|
||||
RtlInitUnicodeString(&VolumeNameU, VolumeNameU.Buffer);
|
||||
/* Convert to ANSI */
|
||||
Status = RtlUnicodeStringToAnsiString(&VolumeName, &VolumeNameU, FALSE);
|
||||
/* If conversion failed, force failure, otherwise, just null terminate */
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
Ret = FALSE;
|
||||
BaseSetLastNTError(Status);
|
||||
}
|
||||
else
|
||||
{
|
||||
VolumeName.Buffer[VolumeName.Length] = ANSI_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Internal buffer no longer needed */
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeNameU.Buffer);
|
||||
|
||||
return Ret;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
@@ -1050,52 +1050,6 @@ MoveFileWithProgressW(IN LPCWSTR lpExistingFileName,
|
||||
return Ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
WINAPI
|
||||
MoveFileWithProgressA(IN LPCSTR lpExistingFileName,
|
||||
IN LPCSTR lpNewFileName OPTIONAL,
|
||||
IN LPPROGRESS_ROUTINE lpProgressRoutine OPTIONAL,
|
||||
IN LPVOID lpData OPTIONAL,
|
||||
IN DWORD dwFlags)
|
||||
{
|
||||
BOOL Ret;
|
||||
UNICODE_STRING ExistingFileNameW, NewFileNameW;
|
||||
|
||||
if (!Basep8BitStringToDynamicUnicodeString(&ExistingFileNameW, lpExistingFileName))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (lpNewFileName)
|
||||
{
|
||||
if (!Basep8BitStringToDynamicUnicodeString(&NewFileNameW, lpNewFileName))
|
||||
{
|
||||
RtlFreeUnicodeString(&ExistingFileNameW);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NewFileNameW.Buffer = NULL;
|
||||
}
|
||||
|
||||
Ret = MoveFileWithProgressW(ExistingFileNameW.Buffer,
|
||||
NewFileNameW.Buffer,
|
||||
lpProgressRoutine,
|
||||
lpData,
|
||||
dwFlags);
|
||||
|
||||
RtlFreeUnicodeString(&ExistingFileNameW);
|
||||
RtlFreeUnicodeString(&NewFileNameW);
|
||||
|
||||
return Ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
@@ -1128,101 +1082,6 @@ MoveFileExW(IN LPCWSTR lpExistingFileName,
|
||||
dwFlags);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
WINAPI
|
||||
MoveFileA(IN LPCSTR lpExistingFileName,
|
||||
IN LPCSTR lpNewFileName)
|
||||
{
|
||||
return MoveFileWithProgressA(lpExistingFileName,
|
||||
lpNewFileName,
|
||||
NULL,
|
||||
NULL,
|
||||
MOVEFILE_COPY_ALLOWED);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
WINAPI
|
||||
MoveFileExA(IN LPCSTR lpExistingFileName,
|
||||
IN LPCSTR lpNewFileName OPTIONAL,
|
||||
IN DWORD dwFlags)
|
||||
{
|
||||
return MoveFileWithProgressA(lpExistingFileName,
|
||||
lpNewFileName,
|
||||
NULL,
|
||||
NULL,
|
||||
dwFlags);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
WINAPI
|
||||
ReplaceFileA(IN LPCSTR lpReplacedFileName,
|
||||
IN LPCSTR lpReplacementFileName,
|
||||
IN LPCSTR lpBackupFileName OPTIONAL,
|
||||
IN DWORD dwReplaceFlags,
|
||||
IN LPVOID lpExclude,
|
||||
IN LPVOID lpReserved)
|
||||
{
|
||||
BOOL Ret;
|
||||
UNICODE_STRING ReplacedFileNameW, ReplacementFileNameW, BackupFileNameW;
|
||||
|
||||
if (!lpReplacedFileName || !lpReplacementFileName || lpExclude || lpReserved ||
|
||||
(dwReplaceFlags & ~(REPLACEFILE_WRITE_THROUGH | REPLACEFILE_IGNORE_MERGE_ERRORS)))
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!Basep8BitStringToDynamicUnicodeString(&ReplacedFileNameW, lpReplacedFileName))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!Basep8BitStringToDynamicUnicodeString(&ReplacementFileNameW, lpReplacementFileName))
|
||||
{
|
||||
RtlFreeUnicodeString(&ReplacedFileNameW);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (lpBackupFileName)
|
||||
{
|
||||
if (!Basep8BitStringToDynamicUnicodeString(&BackupFileNameW, lpBackupFileName))
|
||||
{
|
||||
RtlFreeUnicodeString(&ReplacementFileNameW);
|
||||
RtlFreeUnicodeString(&ReplacedFileNameW);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BackupFileNameW.Buffer = NULL;
|
||||
}
|
||||
|
||||
Ret = ReplaceFileW(ReplacedFileNameW.Buffer,
|
||||
ReplacementFileNameW.Buffer,
|
||||
BackupFileNameW.Buffer,
|
||||
dwReplaceFlags, 0, 0);
|
||||
|
||||
if (lpBackupFileName)
|
||||
{
|
||||
RtlFreeUnicodeString(&BackupFileNameW);
|
||||
}
|
||||
RtlFreeUnicodeString(&ReplacementFileNameW);
|
||||
RtlFreeUnicodeString(&ReplacedFileNameW);
|
||||
|
||||
return Ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
* FILE: dll/win32/kernel32/client/file/moveansi.c
|
||||
* PURPOSE: Directory functions
|
||||
* PROGRAMMER: Ariadne ( [email protected])
|
||||
* Gerhard W. Gruber (sparhawk_at_gmx.at)
|
||||
* Dmitry Philippov ([email protected])
|
||||
* Pierre Schweitzer ([email protected])
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <k32.h>
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
WINAPI
|
||||
MoveFileA(IN LPCSTR lpExistingFileName,
|
||||
IN LPCSTR lpNewFileName)
|
||||
{
|
||||
return MoveFileWithProgressA(lpExistingFileName,
|
||||
lpNewFileName,
|
||||
NULL,
|
||||
NULL,
|
||||
MOVEFILE_COPY_ALLOWED);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
WINAPI
|
||||
MoveFileExA(IN LPCSTR lpExistingFileName,
|
||||
IN LPCSTR lpNewFileName OPTIONAL,
|
||||
IN DWORD dwFlags)
|
||||
{
|
||||
return MoveFileWithProgressA(lpExistingFileName,
|
||||
lpNewFileName,
|
||||
NULL,
|
||||
NULL,
|
||||
dwFlags);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
WINAPI
|
||||
ReplaceFileA(IN LPCSTR lpReplacedFileName,
|
||||
IN LPCSTR lpReplacementFileName,
|
||||
IN LPCSTR lpBackupFileName OPTIONAL,
|
||||
IN DWORD dwReplaceFlags,
|
||||
IN LPVOID lpExclude,
|
||||
IN LPVOID lpReserved)
|
||||
{
|
||||
BOOL Ret;
|
||||
UNICODE_STRING ReplacedFileNameW, ReplacementFileNameW, BackupFileNameW;
|
||||
|
||||
if (!lpReplacedFileName || !lpReplacementFileName || lpExclude || lpReserved ||
|
||||
(dwReplaceFlags & ~(REPLACEFILE_WRITE_THROUGH | REPLACEFILE_IGNORE_MERGE_ERRORS)))
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!Basep8BitStringToDynamicUnicodeString(&ReplacedFileNameW, lpReplacedFileName))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!Basep8BitStringToDynamicUnicodeString(&ReplacementFileNameW, lpReplacementFileName))
|
||||
{
|
||||
RtlFreeUnicodeString(&ReplacedFileNameW);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (lpBackupFileName)
|
||||
{
|
||||
if (!Basep8BitStringToDynamicUnicodeString(&BackupFileNameW, lpBackupFileName))
|
||||
{
|
||||
RtlFreeUnicodeString(&ReplacementFileNameW);
|
||||
RtlFreeUnicodeString(&ReplacedFileNameW);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BackupFileNameW.Buffer = NULL;
|
||||
}
|
||||
|
||||
Ret = ReplaceFileW(ReplacedFileNameW.Buffer,
|
||||
ReplacementFileNameW.Buffer,
|
||||
BackupFileNameW.Buffer,
|
||||
dwReplaceFlags, 0, 0);
|
||||
|
||||
if (lpBackupFileName)
|
||||
{
|
||||
RtlFreeUnicodeString(&BackupFileNameW);
|
||||
}
|
||||
RtlFreeUnicodeString(&ReplacementFileNameW);
|
||||
RtlFreeUnicodeString(&ReplacedFileNameW);
|
||||
|
||||
return Ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
WINAPI
|
||||
MoveFileWithProgressA(IN LPCSTR lpExistingFileName,
|
||||
IN LPCSTR lpNewFileName OPTIONAL,
|
||||
IN LPPROGRESS_ROUTINE lpProgressRoutine OPTIONAL,
|
||||
IN LPVOID lpData OPTIONAL,
|
||||
IN DWORD dwFlags)
|
||||
{
|
||||
BOOL Ret;
|
||||
UNICODE_STRING ExistingFileNameW, NewFileNameW;
|
||||
|
||||
if (!Basep8BitStringToDynamicUnicodeString(&ExistingFileNameW, lpExistingFileName))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (lpNewFileName)
|
||||
{
|
||||
if (!Basep8BitStringToDynamicUnicodeString(&NewFileNameW, lpNewFileName))
|
||||
{
|
||||
RtlFreeUnicodeString(&ExistingFileNameW);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NewFileNameW.Buffer = NULL;
|
||||
}
|
||||
|
||||
Ret = MoveFileWithProgressW(ExistingFileNameW.Buffer,
|
||||
NewFileNameW.Buffer,
|
||||
lpProgressRoutine,
|
||||
lpData,
|
||||
dwFlags);
|
||||
|
||||
RtlFreeUnicodeString(&ExistingFileNameW);
|
||||
RtlFreeUnicodeString(&NewFileNameW);
|
||||
|
||||
return Ret;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
@@ -743,70 +743,6 @@ FindVolumeClose(IN HANDLE hFindVolume)
|
||||
return RtlFreeHeap(RtlGetProcessHeap(), 0, hFindVolume);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
WINAPI
|
||||
GetVolumePathNameA(IN LPCSTR lpszFileName,
|
||||
IN LPSTR lpszVolumePathName,
|
||||
IN DWORD cchBufferLength)
|
||||
{
|
||||
BOOL Ret;
|
||||
PUNICODE_STRING FileNameU;
|
||||
ANSI_STRING VolumePathName;
|
||||
UNICODE_STRING VolumePathNameU;
|
||||
|
||||
/* Convert file name to unicode */
|
||||
FileNameU = Basep8BitStringToStaticUnicodeString(lpszFileName);
|
||||
if (FileNameU == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Initialize all the strings we'll need */
|
||||
VolumePathName.Buffer = lpszVolumePathName;
|
||||
VolumePathName.Length = 0;
|
||||
VolumePathName.MaximumLength = cchBufferLength - 1;
|
||||
|
||||
VolumePathNameU.Length = 0;
|
||||
VolumePathNameU.MaximumLength = (cchBufferLength - 1) * sizeof(WCHAR) + sizeof(UNICODE_NULL);
|
||||
/* Allocate a buffer for calling the -W */
|
||||
VolumePathNameU.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, VolumePathNameU.MaximumLength);
|
||||
if (VolumePathNameU.Buffer == NULL)
|
||||
{
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Call the -W implementation */
|
||||
Ret = GetVolumePathNameW(FileNameU->Buffer, VolumePathNameU.Buffer, cchBufferLength);
|
||||
/* If it succeed */
|
||||
if (Ret)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
/* Convert back to ANSI */
|
||||
RtlInitUnicodeString(&VolumePathNameU, VolumePathNameU.Buffer);
|
||||
Status = RtlUnicodeStringToAnsiString(&VolumePathName, &VolumePathNameU, FALSE);
|
||||
/* If conversion failed, just set error code and fail the rest */
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
BaseSetLastNTError(Status);
|
||||
Ret = FALSE;
|
||||
}
|
||||
/* Otherwise, null terminate the string (it's OK, we computed -1) */
|
||||
else
|
||||
{
|
||||
VolumePathName.Buffer[VolumePathName.Length] = ANSI_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Free the buffer allocated for -W call */
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, VolumePathNameU.Buffer);
|
||||
return Ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
* FILE: dll/win32/kernel32/client/file/volumeansi.c
|
||||
* PURPOSE: Volume functions (ANSI)
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <k32.h>
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
WINAPI
|
||||
GetVolumePathNameA(IN LPCSTR lpszFileName,
|
||||
IN LPSTR lpszVolumePathName,
|
||||
IN DWORD cchBufferLength)
|
||||
{
|
||||
BOOL Ret;
|
||||
PUNICODE_STRING FileNameU;
|
||||
ANSI_STRING VolumePathName;
|
||||
UNICODE_STRING VolumePathNameU;
|
||||
|
||||
/* Convert file name to unicode */
|
||||
FileNameU = Basep8BitStringToStaticUnicodeString(lpszFileName);
|
||||
if (FileNameU == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Initialize all the strings we'll need */
|
||||
VolumePathName.Buffer = lpszVolumePathName;
|
||||
VolumePathName.Length = 0;
|
||||
VolumePathName.MaximumLength = cchBufferLength - 1;
|
||||
|
||||
VolumePathNameU.Length = 0;
|
||||
VolumePathNameU.MaximumLength = (cchBufferLength - 1) * sizeof(WCHAR) + sizeof(UNICODE_NULL);
|
||||
/* Allocate a buffer for calling the -W */
|
||||
VolumePathNameU.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, VolumePathNameU.MaximumLength);
|
||||
if (VolumePathNameU.Buffer == NULL)
|
||||
{
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Call the -W implementation */
|
||||
Ret = GetVolumePathNameW(FileNameU->Buffer, VolumePathNameU.Buffer, cchBufferLength);
|
||||
/* If it succeed */
|
||||
if (Ret)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
/* Convert back to ANSI */
|
||||
RtlInitUnicodeString(&VolumePathNameU, VolumePathNameU.Buffer);
|
||||
Status = RtlUnicodeStringToAnsiString(&VolumePathName, &VolumePathNameU, FALSE);
|
||||
/* If conversion failed, just set error code and fail the rest */
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
BaseSetLastNTError(Status);
|
||||
Ret = FALSE;
|
||||
}
|
||||
/* Otherwise, null terminate the string (it's OK, we computed -1) */
|
||||
else
|
||||
{
|
||||
VolumePathName.Buffer[VolumePathName.Length] = ANSI_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Free the buffer allocated for -W call */
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, VolumePathNameU.Buffer);
|
||||
return Ret;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
@@ -1744,87 +1744,6 @@ Quickie:
|
||||
return Result;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
DWORD
|
||||
WINAPI
|
||||
GetShortPathNameA(IN LPCSTR lpszLongPath,
|
||||
OUT LPSTR lpszShortPath,
|
||||
IN DWORD cchBuffer)
|
||||
{
|
||||
ULONG Result, PathLength;
|
||||
PWCHAR ShortPath;
|
||||
NTSTATUS Status;
|
||||
UNICODE_STRING LongPathUni, ShortPathUni;
|
||||
ANSI_STRING ShortPathAnsi;
|
||||
WCHAR ShortPathBuffer[MAX_PATH];
|
||||
|
||||
ShortPath = NULL;
|
||||
ShortPathAnsi.Buffer = NULL;
|
||||
LongPathUni.Buffer = NULL;
|
||||
Result = 0;
|
||||
|
||||
if (!lpszLongPath)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Status = Basep8BitStringToDynamicUnicodeString(&LongPathUni, lpszLongPath);
|
||||
if (!NT_SUCCESS(Status)) goto Quickie;
|
||||
|
||||
ShortPath = ShortPathBuffer;
|
||||
|
||||
PathLength = GetShortPathNameW(LongPathUni.Buffer, ShortPathBuffer, MAX_PATH);
|
||||
if (PathLength >= MAX_PATH)
|
||||
{
|
||||
ShortPath = RtlAllocateHeap(RtlGetProcessHeap(), 0, PathLength * sizeof(WCHAR));
|
||||
if (!ShortPath)
|
||||
{
|
||||
PathLength = 0;
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
}
|
||||
else
|
||||
{
|
||||
PathLength = GetShortPathNameW(LongPathUni.Buffer, ShortPath, PathLength);
|
||||
}
|
||||
}
|
||||
|
||||
if (!PathLength) goto Quickie;
|
||||
|
||||
LongPathUni.MaximumLength = (USHORT)PathLength * sizeof(WCHAR) + sizeof(UNICODE_NULL);
|
||||
ShortPathUni.Buffer = ShortPath;
|
||||
ShortPathUni.Length = (USHORT)PathLength * sizeof(WCHAR);
|
||||
|
||||
Status = BasepUnicodeStringTo8BitString(&ShortPathAnsi, &ShortPathUni, TRUE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
BaseSetLastNTError(Status);
|
||||
Result = 0;
|
||||
}
|
||||
|
||||
Result = ShortPathAnsi.Length;
|
||||
if ((lpszShortPath) && (cchBuffer > ShortPathAnsi.Length))
|
||||
{
|
||||
RtlMoveMemory(lpszShortPath, ShortPathAnsi.Buffer, ShortPathAnsi.Length);
|
||||
lpszShortPath[Result] = ANSI_NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
Result = ShortPathAnsi.Length + sizeof(ANSI_NULL);
|
||||
}
|
||||
|
||||
Quickie:
|
||||
if (LongPathUni.Buffer) RtlFreeUnicodeString(&LongPathUni);
|
||||
if (ShortPathAnsi.Buffer) RtlFreeAnsiString(&ShortPathAnsi);
|
||||
if ((ShortPath) && (ShortPath != ShortPathBuffer))
|
||||
{
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, ShortPath);
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* PROJECT: ReactOS Win32 Base API
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: dll/win32/kernel32/client/pathansi.c
|
||||
* PURPOSE: Handles path APIs
|
||||
* PROGRAMMERS: Alex Ionescu ([email protected])
|
||||
*/
|
||||
|
||||
/* INCLUDES *******************************************************************/
|
||||
|
||||
#include <k32.h>
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
DWORD
|
||||
WINAPI
|
||||
GetShortPathNameA(IN LPCSTR lpszLongPath,
|
||||
OUT LPSTR lpszShortPath,
|
||||
IN DWORD cchBuffer)
|
||||
{
|
||||
ULONG Result, PathLength;
|
||||
PWCHAR ShortPath;
|
||||
NTSTATUS Status;
|
||||
UNICODE_STRING LongPathUni, ShortPathUni;
|
||||
ANSI_STRING ShortPathAnsi;
|
||||
WCHAR ShortPathBuffer[MAX_PATH];
|
||||
|
||||
ShortPath = NULL;
|
||||
ShortPathAnsi.Buffer = NULL;
|
||||
LongPathUni.Buffer = NULL;
|
||||
Result = 0;
|
||||
|
||||
if (!lpszLongPath)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Status = Basep8BitStringToDynamicUnicodeString(&LongPathUni, lpszLongPath);
|
||||
if (!NT_SUCCESS(Status)) goto Quickie;
|
||||
|
||||
ShortPath = ShortPathBuffer;
|
||||
|
||||
PathLength = GetShortPathNameW(LongPathUni.Buffer, ShortPathBuffer, MAX_PATH);
|
||||
if (PathLength >= MAX_PATH)
|
||||
{
|
||||
ShortPath = RtlAllocateHeap(RtlGetProcessHeap(), 0, PathLength * sizeof(WCHAR));
|
||||
if (!ShortPath)
|
||||
{
|
||||
PathLength = 0;
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
}
|
||||
else
|
||||
{
|
||||
PathLength = GetShortPathNameW(LongPathUni.Buffer, ShortPath, PathLength);
|
||||
}
|
||||
}
|
||||
|
||||
if (!PathLength) goto Quickie;
|
||||
|
||||
LongPathUni.MaximumLength = (USHORT)PathLength * sizeof(WCHAR) + sizeof(UNICODE_NULL);
|
||||
ShortPathUni.Buffer = ShortPath;
|
||||
ShortPathUni.Length = (USHORT)PathLength * sizeof(WCHAR);
|
||||
|
||||
Status = BasepUnicodeStringTo8BitString(&ShortPathAnsi, &ShortPathUni, TRUE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
BaseSetLastNTError(Status);
|
||||
Result = 0;
|
||||
}
|
||||
|
||||
Result = ShortPathAnsi.Length;
|
||||
if ((lpszShortPath) && (cchBuffer > ShortPathAnsi.Length))
|
||||
{
|
||||
RtlMoveMemory(lpszShortPath, ShortPathAnsi.Buffer, ShortPathAnsi.Length);
|
||||
lpszShortPath[Result] = ANSI_NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
Result = ShortPathAnsi.Length + sizeof(ANSI_NULL);
|
||||
}
|
||||
|
||||
Quickie:
|
||||
if (LongPathUni.Buffer) RtlFreeUnicodeString(&LongPathUni);
|
||||
if (ShortPathAnsi.Buffer) RtlFreeAnsiString(&ShortPathAnsi);
|
||||
if ((ShortPath) && (ShortPath != ShortPathBuffer))
|
||||
{
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, ShortPath);
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
@@ -17,11 +17,9 @@
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
WaitForInputIdleType UserWaitForInputIdleRoutine;
|
||||
UNICODE_STRING BaseUnicodeCommandLine;
|
||||
ANSI_STRING BaseAnsiCommandLine;
|
||||
UNICODE_STRING BasePathVariableName = RTL_CONSTANT_STRING(L"PATH");
|
||||
LPSTARTUPINFOA BaseAnsiStartupInfo = NULL;
|
||||
PLDR_DATA_TABLE_ENTRY BasepExeLdrEntry;
|
||||
BOOLEAN g_AppCertInitialized;
|
||||
BOOLEAN g_HaveAppCerts;
|
||||
@@ -1260,17 +1258,6 @@ OpenProcess(IN DWORD dwDesiredAccess,
|
||||
return ProcessHandle;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
WINAPI
|
||||
RegisterWaitForInputIdle(IN WaitForInputIdleType lpfnRegisterWaitForInputIdle)
|
||||
{
|
||||
/* Write the global function pointer */
|
||||
UserWaitForInputIdleRoutine = lpfnRegisterWaitForInputIdle;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
@@ -1312,151 +1299,6 @@ GetStartupInfoW(IN LPSTARTUPINFOW lpStartupInfo)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
WINAPI
|
||||
GetStartupInfoA(IN LPSTARTUPINFOA lpStartupInfo)
|
||||
{
|
||||
PRTL_USER_PROCESS_PARAMETERS Params;
|
||||
ANSI_STRING TitleString, ShellString, DesktopString;
|
||||
LPSTARTUPINFOA StartupInfo;
|
||||
NTSTATUS Status;
|
||||
|
||||
/* Get the cached information as well as the PEB parameters */
|
||||
StartupInfo = BaseAnsiStartupInfo;
|
||||
Params = NtCurrentPeb()->ProcessParameters;
|
||||
|
||||
/* Check if this is the first time we have to get the cached version */
|
||||
while (!StartupInfo)
|
||||
{
|
||||
/* Create new ANSI startup info */
|
||||
StartupInfo = RtlAllocateHeap(RtlGetProcessHeap(),
|
||||
0,
|
||||
sizeof(*StartupInfo));
|
||||
if (StartupInfo)
|
||||
{
|
||||
/* Zero out string pointers in case we fail to create them */
|
||||
StartupInfo->lpReserved = NULL;
|
||||
StartupInfo->lpDesktop = NULL;
|
||||
StartupInfo->lpTitle = NULL;
|
||||
|
||||
/* Set the size */
|
||||
StartupInfo->cb = sizeof(*StartupInfo);
|
||||
|
||||
/* Copy what's already stored in the PEB */
|
||||
StartupInfo->dwX = Params->StartingX;
|
||||
StartupInfo->dwY = Params->StartingY;
|
||||
StartupInfo->dwXSize = Params->CountX;
|
||||
StartupInfo->dwYSize = Params->CountY;
|
||||
StartupInfo->dwXCountChars = Params->CountCharsX;
|
||||
StartupInfo->dwYCountChars = Params->CountCharsY;
|
||||
StartupInfo->dwFillAttribute = Params->FillAttribute;
|
||||
StartupInfo->dwFlags = Params->WindowFlags;
|
||||
StartupInfo->wShowWindow = (WORD)Params->ShowWindowFlags;
|
||||
StartupInfo->cbReserved2 = Params->RuntimeData.Length;
|
||||
StartupInfo->lpReserved2 = (LPBYTE)Params->RuntimeData.Buffer;
|
||||
StartupInfo->hStdInput = Params->StandardInput;
|
||||
StartupInfo->hStdOutput = Params->StandardOutput;
|
||||
StartupInfo->hStdError = Params->StandardError;
|
||||
|
||||
/* Copy shell info string */
|
||||
Status = RtlUnicodeStringToAnsiString(&ShellString,
|
||||
&Params->ShellInfo,
|
||||
TRUE);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Save it */
|
||||
StartupInfo->lpReserved = ShellString.Buffer;
|
||||
|
||||
/* Copy desktop info string */
|
||||
Status = RtlUnicodeStringToAnsiString(&DesktopString,
|
||||
&Params->DesktopInfo,
|
||||
TRUE);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Save it */
|
||||
StartupInfo->lpDesktop = DesktopString.Buffer;
|
||||
|
||||
/* Copy window title string */
|
||||
Status = RtlUnicodeStringToAnsiString(&TitleString,
|
||||
&Params->WindowTitle,
|
||||
TRUE);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Save it */
|
||||
StartupInfo->lpTitle = TitleString.Buffer;
|
||||
|
||||
/* We finished with the ANSI version, try to cache it */
|
||||
if (!InterlockedCompareExchangePointer((PVOID*)&BaseAnsiStartupInfo,
|
||||
StartupInfo,
|
||||
NULL))
|
||||
{
|
||||
/* We were the first thread through, use the data */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Someone beat us to it, we will use their data instead */
|
||||
Status = STATUS_SUCCESS;
|
||||
|
||||
/* We're going to free our own stuff, but not raise */
|
||||
RtlFreeAnsiString(&TitleString);
|
||||
}
|
||||
RtlFreeAnsiString(&DesktopString);
|
||||
}
|
||||
RtlFreeAnsiString(&ShellString);
|
||||
}
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, StartupInfo);
|
||||
|
||||
/* Get the cached information again: either still NULL or set by another thread */
|
||||
StartupInfo = BaseAnsiStartupInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No memory, fail */
|
||||
Status = STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
/* Raise an error unless we got here due to the race condition */
|
||||
if (!StartupInfo) RtlRaiseStatus(Status);
|
||||
}
|
||||
|
||||
/* Now copy from the cached ANSI version */
|
||||
lpStartupInfo->cb = StartupInfo->cb;
|
||||
lpStartupInfo->lpReserved = StartupInfo->lpReserved;
|
||||
lpStartupInfo->lpDesktop = StartupInfo->lpDesktop;
|
||||
lpStartupInfo->lpTitle = StartupInfo->lpTitle;
|
||||
lpStartupInfo->dwX = StartupInfo->dwX;
|
||||
lpStartupInfo->dwY = StartupInfo->dwY;
|
||||
lpStartupInfo->dwXSize = StartupInfo->dwXSize;
|
||||
lpStartupInfo->dwYSize = StartupInfo->dwYSize;
|
||||
lpStartupInfo->dwXCountChars = StartupInfo->dwXCountChars;
|
||||
lpStartupInfo->dwYCountChars = StartupInfo->dwYCountChars;
|
||||
lpStartupInfo->dwFillAttribute = StartupInfo->dwFillAttribute;
|
||||
lpStartupInfo->dwFlags = StartupInfo->dwFlags;
|
||||
lpStartupInfo->wShowWindow = StartupInfo->wShowWindow;
|
||||
lpStartupInfo->cbReserved2 = StartupInfo->cbReserved2;
|
||||
lpStartupInfo->lpReserved2 = StartupInfo->lpReserved2;
|
||||
|
||||
/* Check if the shell is hijacking the handles for other features */
|
||||
if (lpStartupInfo->dwFlags &
|
||||
(STARTF_USESTDHANDLES | STARTF_USEHOTKEY | STARTF_SHELLPRIVATE))
|
||||
{
|
||||
/* It isn't, so we can return the raw values */
|
||||
lpStartupInfo->hStdInput = StartupInfo->hStdInput;
|
||||
lpStartupInfo->hStdOutput = StartupInfo->hStdOutput;
|
||||
lpStartupInfo->hStdError = StartupInfo->hStdError;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* It is, so make sure nobody uses these as console handles */
|
||||
lpStartupInfo->hStdInput = INVALID_HANDLE_VALUE;
|
||||
lpStartupInfo->hStdOutput = INVALID_HANDLE_VALUE;
|
||||
lpStartupInfo->hStdError = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
@@ -4623,198 +4465,4 @@ CreateProcessW(LPCWSTR lpApplicationName,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
WINAPI
|
||||
CreateProcessInternalA(HANDLE hToken,
|
||||
LPCSTR lpApplicationName,
|
||||
LPSTR lpCommandLine,
|
||||
LPSECURITY_ATTRIBUTES lpProcessAttributes,
|
||||
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||||
BOOL bInheritHandles,
|
||||
DWORD dwCreationFlags,
|
||||
LPVOID lpEnvironment,
|
||||
LPCSTR lpCurrentDirectory,
|
||||
LPSTARTUPINFOA lpStartupInfo,
|
||||
LPPROCESS_INFORMATION lpProcessInformation,
|
||||
PHANDLE hNewToken)
|
||||
{
|
||||
UNICODE_STRING CommandLine;
|
||||
UNICODE_STRING ApplicationName;
|
||||
UNICODE_STRING CurrentDirectory;
|
||||
BOOL bRetVal;
|
||||
STARTUPINFOW StartupInfo;
|
||||
|
||||
DPRINT("dwCreationFlags %x, lpEnvironment %p, lpCurrentDirectory %p, "
|
||||
"lpStartupInfo %p, lpProcessInformation %p\n",
|
||||
dwCreationFlags, lpEnvironment, lpCurrentDirectory,
|
||||
lpStartupInfo, lpProcessInformation);
|
||||
|
||||
/* Copy Startup Info */
|
||||
RtlMoveMemory(&StartupInfo, lpStartupInfo, sizeof(*lpStartupInfo));
|
||||
|
||||
/* Initialize all strings to nothing */
|
||||
CommandLine.Buffer = NULL;
|
||||
ApplicationName.Buffer = NULL;
|
||||
CurrentDirectory.Buffer = NULL;
|
||||
StartupInfo.lpDesktop = NULL;
|
||||
StartupInfo.lpReserved = NULL;
|
||||
StartupInfo.lpTitle = NULL;
|
||||
|
||||
/* Convert the Command line */
|
||||
if (lpCommandLine)
|
||||
{
|
||||
Basep8BitStringToDynamicUnicodeString(&CommandLine,
|
||||
lpCommandLine);
|
||||
}
|
||||
|
||||
/* Convert the Name and Directory */
|
||||
if (lpApplicationName)
|
||||
{
|
||||
Basep8BitStringToDynamicUnicodeString(&ApplicationName,
|
||||
lpApplicationName);
|
||||
}
|
||||
if (lpCurrentDirectory)
|
||||
{
|
||||
Basep8BitStringToDynamicUnicodeString(&CurrentDirectory,
|
||||
lpCurrentDirectory);
|
||||
}
|
||||
|
||||
/* Now convert Startup Strings */
|
||||
if (lpStartupInfo->lpReserved)
|
||||
{
|
||||
BasepAnsiStringToHeapUnicodeString(lpStartupInfo->lpReserved,
|
||||
&StartupInfo.lpReserved);
|
||||
}
|
||||
if (lpStartupInfo->lpDesktop)
|
||||
{
|
||||
BasepAnsiStringToHeapUnicodeString(lpStartupInfo->lpDesktop,
|
||||
&StartupInfo.lpDesktop);
|
||||
}
|
||||
if (lpStartupInfo->lpTitle)
|
||||
{
|
||||
BasepAnsiStringToHeapUnicodeString(lpStartupInfo->lpTitle,
|
||||
&StartupInfo.lpTitle);
|
||||
}
|
||||
|
||||
/* Call the Unicode function */
|
||||
bRetVal = CreateProcessInternalW(hToken,
|
||||
ApplicationName.Buffer,
|
||||
CommandLine.Buffer,
|
||||
lpProcessAttributes,
|
||||
lpThreadAttributes,
|
||||
bInheritHandles,
|
||||
dwCreationFlags,
|
||||
lpEnvironment,
|
||||
CurrentDirectory.Buffer,
|
||||
&StartupInfo,
|
||||
lpProcessInformation,
|
||||
hNewToken);
|
||||
|
||||
/* Clean up */
|
||||
RtlFreeUnicodeString(&ApplicationName);
|
||||
RtlFreeUnicodeString(&CommandLine);
|
||||
RtlFreeUnicodeString(&CurrentDirectory);
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, StartupInfo.lpDesktop);
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, StartupInfo.lpReserved);
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, StartupInfo.lpTitle);
|
||||
|
||||
/* Return what Unicode did */
|
||||
return bRetVal;
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: The CreateProcess function creates a new process and its
|
||||
* primary thread. The new process executes the specified executable file
|
||||
* ARGUMENTS:
|
||||
*
|
||||
* lpApplicationName = Pointer to name of executable module
|
||||
* lpCommandLine = Pointer to command line string
|
||||
* lpProcessAttributes = Process security attributes
|
||||
* lpThreadAttributes = Thread security attributes
|
||||
* bInheritHandles = Handle inheritance flag
|
||||
* dwCreationFlags = Creation flags
|
||||
* lpEnvironment = Pointer to new environment block
|
||||
* lpCurrentDirectory = Pointer to current directory name
|
||||
* lpStartupInfo = Pointer to startup info
|
||||
* lpProcessInformation = Pointer to process information
|
||||
*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
WINAPI
|
||||
DECLSPEC_HOTPATCH
|
||||
CreateProcessA(LPCSTR lpApplicationName,
|
||||
LPSTR lpCommandLine,
|
||||
LPSECURITY_ATTRIBUTES lpProcessAttributes,
|
||||
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||||
BOOL bInheritHandles,
|
||||
DWORD dwCreationFlags,
|
||||
LPVOID lpEnvironment,
|
||||
LPCSTR lpCurrentDirectory,
|
||||
LPSTARTUPINFOA lpStartupInfo,
|
||||
LPPROCESS_INFORMATION lpProcessInformation)
|
||||
{
|
||||
/* Call the internal (but exported) version */
|
||||
return CreateProcessInternalA(NULL,
|
||||
lpApplicationName,
|
||||
lpCommandLine,
|
||||
lpProcessAttributes,
|
||||
lpThreadAttributes,
|
||||
bInheritHandles,
|
||||
dwCreationFlags,
|
||||
lpEnvironment,
|
||||
lpCurrentDirectory,
|
||||
lpStartupInfo,
|
||||
lpProcessInformation,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
UINT
|
||||
WINAPI
|
||||
DECLSPEC_HOTPATCH
|
||||
WinExec(LPCSTR lpCmdLine,
|
||||
UINT uCmdShow)
|
||||
{
|
||||
STARTUPINFOA StartupInfo;
|
||||
PROCESS_INFORMATION ProcessInformation;
|
||||
DWORD dosErr;
|
||||
|
||||
RtlZeroMemory(&StartupInfo, sizeof(StartupInfo));
|
||||
StartupInfo.cb = sizeof(STARTUPINFOA);
|
||||
StartupInfo.wShowWindow = (WORD)uCmdShow;
|
||||
StartupInfo.dwFlags = 0;
|
||||
|
||||
if (!CreateProcessA(NULL,
|
||||
(PVOID)lpCmdLine,
|
||||
NULL,
|
||||
NULL,
|
||||
FALSE,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
&StartupInfo,
|
||||
&ProcessInformation))
|
||||
{
|
||||
dosErr = GetLastError();
|
||||
return dosErr < 32 ? dosErr : ERROR_BAD_FORMAT;
|
||||
}
|
||||
|
||||
if (NULL != UserWaitForInputIdleRoutine)
|
||||
{
|
||||
UserWaitForInputIdleRoutine(ProcessInformation.hProcess,
|
||||
10000);
|
||||
}
|
||||
|
||||
NtClose(ProcessInformation.hProcess);
|
||||
NtClose(ProcessInformation.hThread);
|
||||
|
||||
return 33; /* Something bigger than 31 means success. */
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
||||
@@ -0,0 +1,394 @@
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
* FILE: dll/win32/kernel32/client/procansi.c
|
||||
* PURPOSE: Process functions
|
||||
* PROGRAMMERS: Ariadne ([email protected])
|
||||
* UPDATE HISTORY:
|
||||
* Created 01/11/98
|
||||
*/
|
||||
|
||||
/* INCLUDES ****************************************************************/
|
||||
|
||||
#include <k32.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
LPSTARTUPINFOA BaseAnsiStartupInfo = NULL;
|
||||
WaitForInputIdleType UserWaitForInputIdleRoutine;
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
WINAPI
|
||||
RegisterWaitForInputIdle(IN WaitForInputIdleType lpfnRegisterWaitForInputIdle)
|
||||
{
|
||||
/* Write the global function pointer */
|
||||
UserWaitForInputIdleRoutine = lpfnRegisterWaitForInputIdle;
|
||||
}
|
||||
|
||||
#if (NTDDI_VERSION < NTDDI_WIN8)
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
WINAPI
|
||||
CreateProcessInternalW(IN HANDLE hUserToken,
|
||||
IN LPCWSTR lpApplicationName,
|
||||
IN LPWSTR lpCommandLine,
|
||||
IN LPSECURITY_ATTRIBUTES lpProcessAttributes,
|
||||
IN LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||||
IN BOOL bInheritHandles,
|
||||
IN DWORD dwCreationFlags,
|
||||
IN LPVOID lpEnvironment,
|
||||
IN LPCWSTR lpCurrentDirectory,
|
||||
IN LPSTARTUPINFOW lpStartupInfo,
|
||||
IN LPPROCESS_INFORMATION lpProcessInformation,
|
||||
OUT PHANDLE hNewToken);
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
WINAPI
|
||||
CreateProcessInternalA(HANDLE hToken,
|
||||
LPCSTR lpApplicationName,
|
||||
LPSTR lpCommandLine,
|
||||
LPSECURITY_ATTRIBUTES lpProcessAttributes,
|
||||
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||||
BOOL bInheritHandles,
|
||||
DWORD dwCreationFlags,
|
||||
LPVOID lpEnvironment,
|
||||
LPCSTR lpCurrentDirectory,
|
||||
LPSTARTUPINFOA lpStartupInfo,
|
||||
LPPROCESS_INFORMATION lpProcessInformation,
|
||||
PHANDLE hNewToken)
|
||||
{
|
||||
UNICODE_STRING CommandLine;
|
||||
UNICODE_STRING ApplicationName;
|
||||
UNICODE_STRING CurrentDirectory;
|
||||
BOOL bRetVal;
|
||||
STARTUPINFOW StartupInfo;
|
||||
|
||||
DPRINT("dwCreationFlags %x, lpEnvironment %p, lpCurrentDirectory %p, "
|
||||
"lpStartupInfo %p, lpProcessInformation %p\n",
|
||||
dwCreationFlags, lpEnvironment, lpCurrentDirectory,
|
||||
lpStartupInfo, lpProcessInformation);
|
||||
|
||||
/* Copy Startup Info */
|
||||
RtlMoveMemory(&StartupInfo, lpStartupInfo, sizeof(*lpStartupInfo));
|
||||
|
||||
/* Initialize all strings to nothing */
|
||||
CommandLine.Buffer = NULL;
|
||||
ApplicationName.Buffer = NULL;
|
||||
CurrentDirectory.Buffer = NULL;
|
||||
StartupInfo.lpDesktop = NULL;
|
||||
StartupInfo.lpReserved = NULL;
|
||||
StartupInfo.lpTitle = NULL;
|
||||
|
||||
/* Convert the Command line */
|
||||
if (lpCommandLine)
|
||||
{
|
||||
Basep8BitStringToDynamicUnicodeString(&CommandLine,
|
||||
lpCommandLine);
|
||||
}
|
||||
|
||||
/* Convert the Name and Directory */
|
||||
if (lpApplicationName)
|
||||
{
|
||||
Basep8BitStringToDynamicUnicodeString(&ApplicationName,
|
||||
lpApplicationName);
|
||||
}
|
||||
if (lpCurrentDirectory)
|
||||
{
|
||||
Basep8BitStringToDynamicUnicodeString(&CurrentDirectory,
|
||||
lpCurrentDirectory);
|
||||
}
|
||||
|
||||
/* Now convert Startup Strings */
|
||||
if (lpStartupInfo->lpReserved)
|
||||
{
|
||||
BasepAnsiStringToHeapUnicodeString(lpStartupInfo->lpReserved,
|
||||
&StartupInfo.lpReserved);
|
||||
}
|
||||
if (lpStartupInfo->lpDesktop)
|
||||
{
|
||||
BasepAnsiStringToHeapUnicodeString(lpStartupInfo->lpDesktop,
|
||||
&StartupInfo.lpDesktop);
|
||||
}
|
||||
if (lpStartupInfo->lpTitle)
|
||||
{
|
||||
BasepAnsiStringToHeapUnicodeString(lpStartupInfo->lpTitle,
|
||||
&StartupInfo.lpTitle);
|
||||
}
|
||||
|
||||
/* Call the Unicode function */
|
||||
bRetVal = CreateProcessInternalW(hToken,
|
||||
ApplicationName.Buffer,
|
||||
CommandLine.Buffer,
|
||||
lpProcessAttributes,
|
||||
lpThreadAttributes,
|
||||
bInheritHandles,
|
||||
dwCreationFlags,
|
||||
lpEnvironment,
|
||||
CurrentDirectory.Buffer,
|
||||
&StartupInfo,
|
||||
lpProcessInformation,
|
||||
hNewToken);
|
||||
|
||||
/* Clean up */
|
||||
RtlFreeUnicodeString(&ApplicationName);
|
||||
RtlFreeUnicodeString(&CommandLine);
|
||||
RtlFreeUnicodeString(&CurrentDirectory);
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, StartupInfo.lpDesktop);
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, StartupInfo.lpReserved);
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, StartupInfo.lpTitle);
|
||||
|
||||
/* Return what Unicode did */
|
||||
return bRetVal;
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: The CreateProcess function creates a new process and its
|
||||
* primary thread. The new process executes the specified executable file
|
||||
* ARGUMENTS:
|
||||
*
|
||||
* lpApplicationName = Pointer to name of executable module
|
||||
* lpCommandLine = Pointer to command line string
|
||||
* lpProcessAttributes = Process security attributes
|
||||
* lpThreadAttributes = Thread security attributes
|
||||
* bInheritHandles = Handle inheritance flag
|
||||
* dwCreationFlags = Creation flags
|
||||
* lpEnvironment = Pointer to new environment block
|
||||
* lpCurrentDirectory = Pointer to current directory name
|
||||
* lpStartupInfo = Pointer to startup info
|
||||
* lpProcessInformation = Pointer to process information
|
||||
*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
WINAPI
|
||||
DECLSPEC_HOTPATCH
|
||||
CreateProcessA(LPCSTR lpApplicationName,
|
||||
LPSTR lpCommandLine,
|
||||
LPSECURITY_ATTRIBUTES lpProcessAttributes,
|
||||
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||||
BOOL bInheritHandles,
|
||||
DWORD dwCreationFlags,
|
||||
LPVOID lpEnvironment,
|
||||
LPCSTR lpCurrentDirectory,
|
||||
LPSTARTUPINFOA lpStartupInfo,
|
||||
LPPROCESS_INFORMATION lpProcessInformation)
|
||||
{
|
||||
/* Call the internal (but exported) version */
|
||||
return CreateProcessInternalA(NULL,
|
||||
lpApplicationName,
|
||||
lpCommandLine,
|
||||
lpProcessAttributes,
|
||||
lpThreadAttributes,
|
||||
bInheritHandles,
|
||||
dwCreationFlags,
|
||||
lpEnvironment,
|
||||
lpCurrentDirectory,
|
||||
lpStartupInfo,
|
||||
lpProcessInformation,
|
||||
NULL);
|
||||
}
|
||||
#endif // NTDDI_VERSION < NTDDI_WIN8
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
WINAPI
|
||||
GetStartupInfoA(IN LPSTARTUPINFOA lpStartupInfo)
|
||||
{
|
||||
PRTL_USER_PROCESS_PARAMETERS Params;
|
||||
ANSI_STRING TitleString, ShellString, DesktopString;
|
||||
LPSTARTUPINFOA StartupInfo;
|
||||
NTSTATUS Status;
|
||||
|
||||
/* Get the cached information as well as the PEB parameters */
|
||||
StartupInfo = BaseAnsiStartupInfo;
|
||||
Params = NtCurrentPeb()->ProcessParameters;
|
||||
|
||||
/* Check if this is the first time we have to get the cached version */
|
||||
while (!StartupInfo)
|
||||
{
|
||||
/* Create new ANSI startup info */
|
||||
StartupInfo = RtlAllocateHeap(RtlGetProcessHeap(),
|
||||
0,
|
||||
sizeof(*StartupInfo));
|
||||
if (StartupInfo)
|
||||
{
|
||||
/* Zero out string pointers in case we fail to create them */
|
||||
StartupInfo->lpReserved = NULL;
|
||||
StartupInfo->lpDesktop = NULL;
|
||||
StartupInfo->lpTitle = NULL;
|
||||
|
||||
/* Set the size */
|
||||
StartupInfo->cb = sizeof(*StartupInfo);
|
||||
|
||||
/* Copy what's already stored in the PEB */
|
||||
StartupInfo->dwX = Params->StartingX;
|
||||
StartupInfo->dwY = Params->StartingY;
|
||||
StartupInfo->dwXSize = Params->CountX;
|
||||
StartupInfo->dwYSize = Params->CountY;
|
||||
StartupInfo->dwXCountChars = Params->CountCharsX;
|
||||
StartupInfo->dwYCountChars = Params->CountCharsY;
|
||||
StartupInfo->dwFillAttribute = Params->FillAttribute;
|
||||
StartupInfo->dwFlags = Params->WindowFlags;
|
||||
StartupInfo->wShowWindow = (WORD)Params->ShowWindowFlags;
|
||||
StartupInfo->cbReserved2 = Params->RuntimeData.Length;
|
||||
StartupInfo->lpReserved2 = (LPBYTE)Params->RuntimeData.Buffer;
|
||||
StartupInfo->hStdInput = Params->StandardInput;
|
||||
StartupInfo->hStdOutput = Params->StandardOutput;
|
||||
StartupInfo->hStdError = Params->StandardError;
|
||||
|
||||
/* Copy shell info string */
|
||||
Status = RtlUnicodeStringToAnsiString(&ShellString,
|
||||
&Params->ShellInfo,
|
||||
TRUE);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Save it */
|
||||
StartupInfo->lpReserved = ShellString.Buffer;
|
||||
|
||||
/* Copy desktop info string */
|
||||
Status = RtlUnicodeStringToAnsiString(&DesktopString,
|
||||
&Params->DesktopInfo,
|
||||
TRUE);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Save it */
|
||||
StartupInfo->lpDesktop = DesktopString.Buffer;
|
||||
|
||||
/* Copy window title string */
|
||||
Status = RtlUnicodeStringToAnsiString(&TitleString,
|
||||
&Params->WindowTitle,
|
||||
TRUE);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Save it */
|
||||
StartupInfo->lpTitle = TitleString.Buffer;
|
||||
|
||||
/* We finished with the ANSI version, try to cache it */
|
||||
if (!InterlockedCompareExchangePointer((PVOID*)&BaseAnsiStartupInfo,
|
||||
StartupInfo,
|
||||
NULL))
|
||||
{
|
||||
/* We were the first thread through, use the data */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Someone beat us to it, we will use their data instead */
|
||||
Status = STATUS_SUCCESS;
|
||||
|
||||
/* We're going to free our own stuff, but not raise */
|
||||
RtlFreeAnsiString(&TitleString);
|
||||
}
|
||||
RtlFreeAnsiString(&DesktopString);
|
||||
}
|
||||
RtlFreeAnsiString(&ShellString);
|
||||
}
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, StartupInfo);
|
||||
|
||||
/* Get the cached information again: either still NULL or set by another thread */
|
||||
StartupInfo = BaseAnsiStartupInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No memory, fail */
|
||||
Status = STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
/* Raise an error unless we got here due to the race condition */
|
||||
if (!StartupInfo) RtlRaiseStatus(Status);
|
||||
}
|
||||
|
||||
/* Now copy from the cached ANSI version */
|
||||
lpStartupInfo->cb = StartupInfo->cb;
|
||||
lpStartupInfo->lpReserved = StartupInfo->lpReserved;
|
||||
lpStartupInfo->lpDesktop = StartupInfo->lpDesktop;
|
||||
lpStartupInfo->lpTitle = StartupInfo->lpTitle;
|
||||
lpStartupInfo->dwX = StartupInfo->dwX;
|
||||
lpStartupInfo->dwY = StartupInfo->dwY;
|
||||
lpStartupInfo->dwXSize = StartupInfo->dwXSize;
|
||||
lpStartupInfo->dwYSize = StartupInfo->dwYSize;
|
||||
lpStartupInfo->dwXCountChars = StartupInfo->dwXCountChars;
|
||||
lpStartupInfo->dwYCountChars = StartupInfo->dwYCountChars;
|
||||
lpStartupInfo->dwFillAttribute = StartupInfo->dwFillAttribute;
|
||||
lpStartupInfo->dwFlags = StartupInfo->dwFlags;
|
||||
lpStartupInfo->wShowWindow = StartupInfo->wShowWindow;
|
||||
lpStartupInfo->cbReserved2 = StartupInfo->cbReserved2;
|
||||
lpStartupInfo->lpReserved2 = StartupInfo->lpReserved2;
|
||||
|
||||
/* Check if the shell is hijacking the handles for other features */
|
||||
if (lpStartupInfo->dwFlags &
|
||||
(STARTF_USESTDHANDLES | STARTF_USEHOTKEY | STARTF_SHELLPRIVATE))
|
||||
{
|
||||
/* It isn't, so we can return the raw values */
|
||||
lpStartupInfo->hStdInput = StartupInfo->hStdInput;
|
||||
lpStartupInfo->hStdOutput = StartupInfo->hStdOutput;
|
||||
lpStartupInfo->hStdError = StartupInfo->hStdError;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* It is, so make sure nobody uses these as console handles */
|
||||
lpStartupInfo->hStdInput = INVALID_HANDLE_VALUE;
|
||||
lpStartupInfo->hStdOutput = INVALID_HANDLE_VALUE;
|
||||
lpStartupInfo->hStdError = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
UINT
|
||||
WINAPI
|
||||
DECLSPEC_HOTPATCH
|
||||
WinExec(LPCSTR lpCmdLine,
|
||||
UINT uCmdShow)
|
||||
{
|
||||
STARTUPINFOA StartupInfo;
|
||||
PROCESS_INFORMATION ProcessInformation;
|
||||
DWORD dosErr;
|
||||
|
||||
RtlZeroMemory(&StartupInfo, sizeof(StartupInfo));
|
||||
StartupInfo.cb = sizeof(STARTUPINFOA);
|
||||
StartupInfo.wShowWindow = (WORD)uCmdShow;
|
||||
StartupInfo.dwFlags = 0;
|
||||
|
||||
if (!CreateProcessA(NULL,
|
||||
(PVOID)lpCmdLine,
|
||||
NULL,
|
||||
NULL,
|
||||
FALSE,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
&StartupInfo,
|
||||
&ProcessInformation))
|
||||
{
|
||||
dosErr = GetLastError();
|
||||
return dosErr < 32 ? dosErr : ERROR_BAD_FORMAT;
|
||||
}
|
||||
|
||||
if (NULL != UserWaitForInputIdleRoutine)
|
||||
{
|
||||
UserWaitForInputIdleRoutine(ProcessInformation.hProcess,
|
||||
10000);
|
||||
}
|
||||
|
||||
NtClose(ProcessInformation.hProcess);
|
||||
NtClose(ProcessInformation.hThread);
|
||||
|
||||
return 33; /* Something bigger than 31 means success. */
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
@@ -338,18 +338,6 @@ CreateWaitableTimerW(IN LPSECURITY_ATTRIBUTES lpTimerAttributes OPTIONAL,
|
||||
bManualReset ? NotificationTimer : SynchronizationTimer);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
HANDLE
|
||||
WINAPI
|
||||
CreateWaitableTimerA(IN LPSECURITY_ATTRIBUTES lpTimerAttributes OPTIONAL,
|
||||
IN BOOL bManualReset,
|
||||
IN LPCSTR lpTimerName OPTIONAL)
|
||||
{
|
||||
ConvertWin32AnsiObjectApiToUnicodeApi(WaitableTimer, lpTimerName, lpTimerAttributes, bManualReset);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
@@ -362,18 +350,6 @@ OpenWaitableTimerW(IN DWORD dwDesiredAccess,
|
||||
OpenNtObjectFromWin32Api(Timer, dwDesiredAccess, bInheritHandle, lpTimerName);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
HANDLE
|
||||
WINAPI
|
||||
OpenWaitableTimerA(IN DWORD dwDesiredAccess,
|
||||
IN BOOL bInheritHandle,
|
||||
IN LPCSTR lpTimerName)
|
||||
{
|
||||
ConvertOpenWin32AnsiObjectApiToUnicodeApi(WaitableTimer, dwDesiredAccess, bInheritHandle, lpTimerName);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
@@ -421,20 +397,6 @@ CancelWaitableTimer(IN HANDLE hTimer)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
HANDLE
|
||||
WINAPI
|
||||
DECLSPEC_HOTPATCH
|
||||
CreateSemaphoreA(IN LPSECURITY_ATTRIBUTES lpSemaphoreAttributes OPTIONAL,
|
||||
IN LONG lInitialCount,
|
||||
IN LONG lMaximumCount,
|
||||
IN LPCSTR lpName OPTIONAL)
|
||||
{
|
||||
ConvertWin32AnsiObjectApiToUnicodeApi(Semaphore, lpName, lpSemaphoreAttributes, lInitialCount, lMaximumCount);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
@@ -507,19 +469,6 @@ CreateSemaphoreExA(IN LPSECURITY_ATTRIBUTES lpSemaphoreAttributes OPTIONAL,
|
||||
ConvertAnsiToUnicodeEpilogue
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
HANDLE
|
||||
WINAPI
|
||||
DECLSPEC_HOTPATCH
|
||||
OpenSemaphoreA(IN DWORD dwDesiredAccess,
|
||||
IN BOOL bInheritHandle,
|
||||
IN LPCSTR lpName)
|
||||
{
|
||||
ConvertOpenWin32AnsiObjectApiToUnicodeApi(Semaphore, dwDesiredAccess, bInheritHandle, lpName);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
@@ -583,19 +532,6 @@ CreateMutexW(IN LPSECURITY_ATTRIBUTES lpMutexAttributes OPTIONAL,
|
||||
bInitialOwner);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
HANDLE
|
||||
WINAPI
|
||||
DECLSPEC_HOTPATCH
|
||||
OpenMutexA(IN DWORD dwDesiredAccess,
|
||||
IN BOOL bInheritHandle,
|
||||
IN LPCSTR lpName)
|
||||
{
|
||||
ConvertOpenWin32AnsiObjectApiToUnicodeApi(Mutex, dwDesiredAccess, bInheritHandle, lpName);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
* FILE: dll/win32/kernel32/client/synchansi.c
|
||||
* PURPOSE: Synchronization functions (ANSI)
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <k32.h>
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
HANDLE
|
||||
WINAPI
|
||||
CreateWaitableTimerA(IN LPSECURITY_ATTRIBUTES lpTimerAttributes OPTIONAL,
|
||||
IN BOOL bManualReset,
|
||||
IN LPCSTR lpTimerName OPTIONAL)
|
||||
{
|
||||
ConvertWin32AnsiObjectApiToUnicodeApi(WaitableTimer, lpTimerName, lpTimerAttributes, bManualReset);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
HANDLE
|
||||
WINAPI
|
||||
OpenWaitableTimerA(IN DWORD dwDesiredAccess,
|
||||
IN BOOL bInheritHandle,
|
||||
IN LPCSTR lpTimerName)
|
||||
{
|
||||
ConvertOpenWin32AnsiObjectApiToUnicodeApi(WaitableTimer, dwDesiredAccess, bInheritHandle, lpTimerName);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
HANDLE
|
||||
WINAPI
|
||||
DECLSPEC_HOTPATCH
|
||||
CreateSemaphoreA(IN LPSECURITY_ATTRIBUTES lpSemaphoreAttributes OPTIONAL,
|
||||
IN LONG lInitialCount,
|
||||
IN LONG lMaximumCount,
|
||||
IN LPCSTR lpName OPTIONAL)
|
||||
{
|
||||
ConvertWin32AnsiObjectApiToUnicodeApi(Semaphore, lpName, lpSemaphoreAttributes, lInitialCount, lMaximumCount);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
HANDLE
|
||||
WINAPI
|
||||
DECLSPEC_HOTPATCH
|
||||
OpenSemaphoreA(IN DWORD dwDesiredAccess,
|
||||
IN BOOL bInheritHandle,
|
||||
IN LPCSTR lpName)
|
||||
{
|
||||
ConvertOpenWin32AnsiObjectApiToUnicodeApi(Semaphore, dwDesiredAccess, bInheritHandle, lpName);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
HANDLE
|
||||
WINAPI
|
||||
DECLSPEC_HOTPATCH
|
||||
OpenMutexA(IN DWORD dwDesiredAccess,
|
||||
IN BOOL bInheritHandle,
|
||||
IN LPCSTR lpName)
|
||||
{
|
||||
ConvertOpenWin32AnsiObjectApiToUnicodeApi(Mutex, dwDesiredAccess, bInheritHandle, lpName);
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
@@ -464,18 +464,6 @@ GetFirmwareEnvironmentVariableW(
|
||||
return GetFirmwareEnvironmentVariableExW(lpName, lpGuid, pBuffer, nSize, NULL);
|
||||
}
|
||||
|
||||
_Success_(return > 0)
|
||||
DWORD
|
||||
WINAPI
|
||||
GetFirmwareEnvironmentVariableA(
|
||||
_In_ LPCSTR lpName,
|
||||
_In_ LPCSTR lpGuid,
|
||||
_Out_writes_bytes_to_opt_(nSize, return) PVOID pBuffer,
|
||||
_In_ DWORD nSize)
|
||||
{
|
||||
return GetFirmwareEnvironmentVariableExA(lpName, lpGuid, pBuffer, nSize, NULL);
|
||||
}
|
||||
|
||||
BOOL
|
||||
WINAPI
|
||||
SetFirmwareEnvironmentVariableW(
|
||||
@@ -491,21 +479,6 @@ SetFirmwareEnvironmentVariableW(
|
||||
VARIABLE_ATTRIBUTE_NON_VOLATILE);
|
||||
}
|
||||
|
||||
BOOL
|
||||
WINAPI
|
||||
SetFirmwareEnvironmentVariableA(
|
||||
_In_ LPCSTR lpName,
|
||||
_In_ LPCSTR lpGuid,
|
||||
_In_reads_bytes_opt_(nSize) PVOID pValue,
|
||||
_In_ DWORD nSize)
|
||||
{
|
||||
return SetFirmwareEnvironmentVariableExA(lpName,
|
||||
lpGuid,
|
||||
pValue,
|
||||
nSize,
|
||||
VARIABLE_ATTRIBUTE_NON_VOLATILE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @name EnumSystemFirmwareTables
|
||||
* @implemented
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
* FILE: dll/win32/kernel32/client/sysinfoansi.c
|
||||
* PURPOSE: System information functions (ANSI)
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <k32.h>
|
||||
|
||||
/* Forward declarations (may be missing from headers depending on SDK level) */
|
||||
_Success_(return > 0)
|
||||
DWORD
|
||||
WINAPI
|
||||
GetFirmwareEnvironmentVariableExA(
|
||||
_In_ LPCSTR lpName,
|
||||
_In_ LPCSTR lpGuid,
|
||||
_Out_writes_bytes_to_opt_(nSize, return) PVOID pBuffer,
|
||||
_In_ DWORD nSize,
|
||||
_Out_opt_ PDWORD pdwAttribubutes);
|
||||
|
||||
BOOL
|
||||
WINAPI
|
||||
SetFirmwareEnvironmentVariableExA(
|
||||
_In_ LPCSTR lpName,
|
||||
_In_ LPCSTR lpGuid,
|
||||
_In_reads_bytes_opt_(nSize) PVOID pValue,
|
||||
_In_ DWORD nSize,
|
||||
_In_ DWORD dwAttributes);
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
_Success_(return > 0)
|
||||
DWORD
|
||||
WINAPI
|
||||
GetFirmwareEnvironmentVariableA(
|
||||
_In_ LPCSTR lpName,
|
||||
_In_ LPCSTR lpGuid,
|
||||
_Out_writes_bytes_to_opt_(nSize, return) PVOID pBuffer,
|
||||
_In_ DWORD nSize)
|
||||
{
|
||||
return GetFirmwareEnvironmentVariableExA(lpName, lpGuid, pBuffer, nSize, NULL);
|
||||
}
|
||||
|
||||
BOOL
|
||||
WINAPI
|
||||
SetFirmwareEnvironmentVariableA(
|
||||
_In_ LPCSTR lpName,
|
||||
_In_ LPCSTR lpGuid,
|
||||
_In_reads_bytes_opt_(nSize) PVOID pValue,
|
||||
_In_ DWORD nSize)
|
||||
{
|
||||
return SetFirmwareEnvironmentVariableExA(lpName,
|
||||
lpGuid,
|
||||
pValue,
|
||||
nSize,
|
||||
VARIABLE_ATTRIBUTE_NON_VOLATILE);
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
UNICODE_STRING Restricted = RTL_CONSTANT_STRING(L"Restricted");
|
||||
BOOL bIsFileApiAnsi = TRUE; // set the file api to ansi or oem
|
||||
|
||||
PRTL_CONVERT_STRING Basep8BitStringToUnicodeString = RtlAnsiStringToUnicodeString;
|
||||
PRTL_CONVERT_STRINGA BasepUnicodeStringTo8BitString = RtlUnicodeStringToAnsiString;
|
||||
PRTL_COUNT_STRING BasepUnicodeStringTo8BitSize = BasepUnicodeStringToAnsiSize;
|
||||
|
||||
@@ -152,28 +152,3 @@ VerifyVersionInfoW(IN LPOSVERSIONINFOEXW lpVersionInformation,
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
WINAPI
|
||||
VerifyVersionInfoA(IN LPOSVERSIONINFOEXA lpVersionInformation,
|
||||
IN DWORD dwTypeMask,
|
||||
IN DWORDLONG dwlConditionMask)
|
||||
{
|
||||
OSVERSIONINFOEXW viex;
|
||||
|
||||
/* NOTE: szCSDVersion is ignored, we don't need to convert it to Unicode */
|
||||
viex.dwOSVersionInfoSize = sizeof(viex);
|
||||
viex.dwMajorVersion = lpVersionInformation->dwMajorVersion;
|
||||
viex.dwMinorVersion = lpVersionInformation->dwMinorVersion;
|
||||
viex.dwBuildNumber = lpVersionInformation->dwBuildNumber;
|
||||
viex.dwPlatformId = lpVersionInformation->dwPlatformId;
|
||||
viex.wServicePackMajor = lpVersionInformation->wServicePackMajor;
|
||||
viex.wServicePackMinor = lpVersionInformation->wServicePackMinor;
|
||||
viex.wSuiteMask = lpVersionInformation->wSuiteMask;
|
||||
viex.wProductType = lpVersionInformation->wProductType;
|
||||
viex.wReserved = lpVersionInformation->wReserved;
|
||||
return VerifyVersionInfoW(&viex, dwTypeMask, dwlConditionMask);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
* FILE: dll/win32/kernel32/client/versionansi.c
|
||||
* PURPOSE: Version checking (ANSI)
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <k32.h>
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
WINAPI
|
||||
VerifyVersionInfoA(IN LPOSVERSIONINFOEXA lpVersionInformation,
|
||||
IN DWORD dwTypeMask,
|
||||
IN DWORDLONG dwlConditionMask)
|
||||
{
|
||||
OSVERSIONINFOEXW viex;
|
||||
|
||||
/* NOTE: szCSDVersion is ignored, we don't need to convert it to Unicode */
|
||||
viex.dwOSVersionInfoSize = sizeof(viex);
|
||||
viex.dwMajorVersion = lpVersionInformation->dwMajorVersion;
|
||||
viex.dwMinorVersion = lpVersionInformation->dwMinorVersion;
|
||||
viex.dwBuildNumber = lpVersionInformation->dwBuildNumber;
|
||||
viex.dwPlatformId = lpVersionInformation->dwPlatformId;
|
||||
viex.wServicePackMajor = lpVersionInformation->wServicePackMajor;
|
||||
viex.wServicePackMinor = lpVersionInformation->wServicePackMinor;
|
||||
viex.wSuiteMask = lpVersionInformation->wSuiteMask;
|
||||
viex.wProductType = lpVersionInformation->wProductType;
|
||||
viex.wReserved = lpVersionInformation->wReserved;
|
||||
return VerifyVersionInfoW(&viex, dwTypeMask, dwlConditionMask);
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
@@ -27,6 +27,8 @@
|
||||
#include <k32.h>
|
||||
#include "japanese.h" /* Japanese eras */
|
||||
|
||||
#include "lcformat_private.h"
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
DEBUG_CHANNEL(nls);
|
||||
@@ -352,6 +354,16 @@ static const NLS_FORMAT_NODE *NLS_GetFormats(LCID lcid, DWORD dwFlags)
|
||||
return node;
|
||||
}
|
||||
|
||||
/*
|
||||
* NLS_GetAnsiCodePage <internal>
|
||||
* Helper used by ANSI entrypoints to determine the locale codepage.
|
||||
*/
|
||||
DWORD NLS_GetAnsiCodePage(LCID lcid, DWORD dwFlags)
|
||||
{
|
||||
const NLS_FORMAT_NODE *node = NLS_GetFormats(lcid, dwFlags);
|
||||
return node ? node->dwCodePage : 0;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* NLS_IsUnicodeOnlyLcid <internal>
|
||||
*
|
||||
@@ -1096,96 +1108,6 @@ INT WINAPI GetTimeFormatW(LCID lcid, DWORD dwFlags, const SYSTEMTIME* lpTime,
|
||||
lpFormat, lpTimeStr, cchOut);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* GetNumberFormatA (KERNEL32.@)
|
||||
*
|
||||
* Format a number string for a given locale.
|
||||
*
|
||||
* PARAMS
|
||||
* lcid [I] Locale to format for
|
||||
* dwFlags [I] LOCALE_ flags from "winnls.h"
|
||||
* lpszValue [I] String to format
|
||||
* lpFormat [I] Formatting overrides
|
||||
* lpNumberStr [O] Destination for formatted string
|
||||
* cchOut [I] Size of lpNumberStr, or 0 to calculate the resulting size
|
||||
*
|
||||
* NOTES
|
||||
* - lpszValue can contain only '0' - '9', '-' and '.'.
|
||||
* - If lpFormat is non-NULL, dwFlags must be 0. In this case lpszValue will
|
||||
* be formatted according to the format details returned by GetLocaleInfoA().
|
||||
* - This function rounds the number string if the number of decimals exceeds the
|
||||
* locales normal number of decimal places.
|
||||
* - If cchOut is 0, this function does not write to lpNumberStr.
|
||||
* - The Ascii version of this function fails if lcid is Unicode only.
|
||||
*
|
||||
* RETURNS
|
||||
* Success: The number of character written to lpNumberStr, or that would
|
||||
* have been written, if cchOut is 0.
|
||||
* Failure: 0. Use GetLastError() to determine the cause.
|
||||
*/
|
||||
INT WINAPI GetNumberFormatA(LCID lcid, DWORD dwFlags,
|
||||
LPCSTR lpszValue, const NUMBERFMTA *lpFormat,
|
||||
LPSTR lpNumberStr, int cchOut)
|
||||
{
|
||||
DWORD cp = CP_ACP;
|
||||
WCHAR szDec[8], szGrp[8], szIn[128], szOut[128];
|
||||
NUMBERFMTW fmt;
|
||||
const NUMBERFMTW *pfmt = NULL;
|
||||
INT iRet;
|
||||
|
||||
TRACE("(0x%04x,0x%08x,%s,%p,%p,%d)\n", lcid, dwFlags, debugstr_a(lpszValue),
|
||||
lpFormat, lpNumberStr, cchOut);
|
||||
|
||||
if (NLS_IsUnicodeOnlyLcid(lcid))
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(dwFlags & LOCALE_USE_CP_ACP))
|
||||
{
|
||||
const NLS_FORMAT_NODE *node = NLS_GetFormats(lcid, dwFlags);
|
||||
if (!node)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
cp = node->dwCodePage;
|
||||
}
|
||||
|
||||
if (lpFormat)
|
||||
{
|
||||
memcpy(&fmt, lpFormat, sizeof(fmt));
|
||||
pfmt = &fmt;
|
||||
if (lpFormat->lpDecimalSep)
|
||||
{
|
||||
MultiByteToWideChar(cp, 0, lpFormat->lpDecimalSep, -1, szDec, ARRAY_SIZE(szDec));
|
||||
fmt.lpDecimalSep = szDec;
|
||||
}
|
||||
if (lpFormat->lpThousandSep)
|
||||
{
|
||||
MultiByteToWideChar(cp, 0, lpFormat->lpThousandSep, -1, szGrp, ARRAY_SIZE(szGrp));
|
||||
fmt.lpThousandSep = szGrp;
|
||||
}
|
||||
}
|
||||
|
||||
if (lpszValue)
|
||||
MultiByteToWideChar(cp, 0, lpszValue, -1, szIn, ARRAY_SIZE(szIn));
|
||||
|
||||
if (cchOut > (int) ARRAY_SIZE(szOut))
|
||||
cchOut = ARRAY_SIZE(szOut);
|
||||
|
||||
szOut[0] = '\0';
|
||||
|
||||
iRet = GetNumberFormatW(lcid, dwFlags, lpszValue ? szIn : NULL, pfmt,
|
||||
lpNumberStr ? szOut : NULL, cchOut);
|
||||
|
||||
if (szOut[0] && lpNumberStr)
|
||||
WideCharToMultiByte(cp, 0, szOut, -1, lpNumberStr, cchOut, 0, 0);
|
||||
return iRet;
|
||||
}
|
||||
|
||||
/* Number parsing state flags */
|
||||
#define NF_ISNEGATIVE 0x1 /* '-' found */
|
||||
#define NF_ISREAL 0x2 /* '.' found */
|
||||
@@ -1462,101 +1384,6 @@ INT WINAPI GetNumberFormatEx(LPCWSTR name, DWORD flags,
|
||||
}
|
||||
#endif /* _WIN32_WINNT >= 0x600 */
|
||||
|
||||
/**************************************************************************
|
||||
* GetCurrencyFormatA (KERNEL32.@)
|
||||
*
|
||||
* Format a currency string for a given locale.
|
||||
*
|
||||
* PARAMS
|
||||
* lcid [I] Locale to format for
|
||||
* dwFlags [I] LOCALE_ flags from "winnls.h"
|
||||
* lpszValue [I] String to format
|
||||
* lpFormat [I] Formatting overrides
|
||||
* lpCurrencyStr [O] Destination for formatted string
|
||||
* cchOut [I] Size of lpCurrencyStr, or 0 to calculate the resulting size
|
||||
*
|
||||
* NOTES
|
||||
* - lpszValue can contain only '0' - '9', '-' and '.'.
|
||||
* - If lpFormat is non-NULL, dwFlags must be 0. In this case lpszValue will
|
||||
* be formatted according to the format details returned by GetLocaleInfoA().
|
||||
* - This function rounds the currency if the number of decimals exceeds the
|
||||
* locales number of currency decimal places.
|
||||
* - If cchOut is 0, this function does not write to lpCurrencyStr.
|
||||
* - The Ascii version of this function fails if lcid is Unicode only.
|
||||
*
|
||||
* RETURNS
|
||||
* Success: The number of character written to lpNumberStr, or that would
|
||||
* have been written, if cchOut is 0.
|
||||
* Failure: 0. Use GetLastError() to determine the cause.
|
||||
*/
|
||||
INT WINAPI GetCurrencyFormatA(LCID lcid, DWORD dwFlags,
|
||||
LPCSTR lpszValue, const CURRENCYFMTA *lpFormat,
|
||||
LPSTR lpCurrencyStr, int cchOut)
|
||||
{
|
||||
DWORD cp = CP_ACP;
|
||||
WCHAR szDec[8], szGrp[8], szCy[8], szIn[128], szOut[128];
|
||||
CURRENCYFMTW fmt;
|
||||
const CURRENCYFMTW *pfmt = NULL;
|
||||
INT iRet;
|
||||
|
||||
TRACE("(0x%04x,0x%08x,%s,%p,%p,%d)\n", lcid, dwFlags, debugstr_a(lpszValue),
|
||||
lpFormat, lpCurrencyStr, cchOut);
|
||||
|
||||
if (NLS_IsUnicodeOnlyLcid(lcid))
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(dwFlags & LOCALE_USE_CP_ACP))
|
||||
{
|
||||
const NLS_FORMAT_NODE *node = NLS_GetFormats(lcid, dwFlags);
|
||||
if (!node)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
cp = node->dwCodePage;
|
||||
}
|
||||
|
||||
if (lpFormat)
|
||||
{
|
||||
memcpy(&fmt, lpFormat, sizeof(fmt));
|
||||
pfmt = &fmt;
|
||||
if (lpFormat->lpDecimalSep)
|
||||
{
|
||||
MultiByteToWideChar(cp, 0, lpFormat->lpDecimalSep, -1, szDec, ARRAY_SIZE(szDec));
|
||||
fmt.lpDecimalSep = szDec;
|
||||
}
|
||||
if (lpFormat->lpThousandSep)
|
||||
{
|
||||
MultiByteToWideChar(cp, 0, lpFormat->lpThousandSep, -1, szGrp, ARRAY_SIZE(szGrp));
|
||||
fmt.lpThousandSep = szGrp;
|
||||
}
|
||||
if (lpFormat->lpCurrencySymbol)
|
||||
{
|
||||
MultiByteToWideChar(cp, 0, lpFormat->lpCurrencySymbol, -1, szCy, ARRAY_SIZE(szCy));
|
||||
fmt.lpCurrencySymbol = szCy;
|
||||
}
|
||||
}
|
||||
|
||||
if (lpszValue)
|
||||
MultiByteToWideChar(cp, 0, lpszValue, -1, szIn, ARRAY_SIZE(szIn));
|
||||
|
||||
if (cchOut > (int) ARRAY_SIZE(szOut))
|
||||
cchOut = ARRAY_SIZE(szOut);
|
||||
|
||||
szOut[0] = '\0';
|
||||
|
||||
iRet = GetCurrencyFormatW(lcid, dwFlags, lpszValue ? szIn : NULL, pfmt,
|
||||
lpCurrencyStr ? szOut : NULL, cchOut);
|
||||
|
||||
if (szOut[0] && lpCurrencyStr)
|
||||
WideCharToMultiByte(cp, 0, szOut, -1, lpCurrencyStr, cchOut, 0, 0);
|
||||
return iRet;
|
||||
}
|
||||
|
||||
/* Formatting states for Currencies. We use flags to avoid code duplication. */
|
||||
#define CF_PARENS 0x1 /* Parentheses */
|
||||
#define CF_MINUS_LEFT 0x2 /* '-' to the left */
|
||||
@@ -1877,24 +1704,7 @@ int WINAPI GetCurrencyFormatEx(LPCWSTR localename, DWORD flags, LPCWSTR value,
|
||||
* alternate calendars is determined.
|
||||
*/
|
||||
|
||||
enum enum_callback_type {
|
||||
CALLBACK_ENUMPROC,
|
||||
CALLBACK_ENUMPROCEX,
|
||||
CALLBACK_ENUMPROCEXEX
|
||||
};
|
||||
|
||||
struct enumdateformats_context {
|
||||
enum enum_callback_type type; /* callback kind */
|
||||
union {
|
||||
DATEFMT_ENUMPROCW callback; /* user callback pointer */
|
||||
DATEFMT_ENUMPROCEXW callbackex;
|
||||
DATEFMT_ENUMPROCEXEX callbackexex;
|
||||
} u;
|
||||
LCID lcid; /* locale of interest */
|
||||
DWORD flags;
|
||||
LPARAM lParam;
|
||||
BOOL unicode; /* A vs W callback type, only for regular and Ex callbacks */
|
||||
};
|
||||
/* Types for Enum* internals are declared in lcformat_private.h */
|
||||
|
||||
/******************************************************************************
|
||||
* NLS_EnumDateFormats <internal>
|
||||
@@ -1907,7 +1717,7 @@ struct enumdateformats_context {
|
||||
* Success: TRUE.
|
||||
* Failure: FALSE. Use GetLastError() to determine the cause.
|
||||
*/
|
||||
static BOOL NLS_EnumDateFormats(const struct enumdateformats_context *ctxt)
|
||||
BOOL NLS_EnumDateFormats(const struct enumdateformats_context *ctxt)
|
||||
{
|
||||
WCHAR bufW[256];
|
||||
char bufA[256];
|
||||
@@ -2004,25 +1814,6 @@ BOOL WINAPI EnumDateFormatsExW(DATEFMT_ENUMPROCEXW proc, LCID lcid, DWORD flags)
|
||||
return NLS_EnumDateFormats(&ctxt);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* EnumDateFormatsA (KERNEL32.@)
|
||||
*
|
||||
* FIXME: MSDN mentions only LOCALE_USE_CP_ACP, should we handle
|
||||
* LOCALE_NOUSEROVERRIDE here as well?
|
||||
*/
|
||||
BOOL WINAPI EnumDateFormatsA(DATEFMT_ENUMPROCA proc, LCID lcid, DWORD flags)
|
||||
{
|
||||
struct enumdateformats_context ctxt;
|
||||
|
||||
ctxt.type = CALLBACK_ENUMPROC;
|
||||
ctxt.u.callback = (DATEFMT_ENUMPROCW)proc;
|
||||
ctxt.lcid = lcid;
|
||||
ctxt.flags = flags;
|
||||
ctxt.unicode = FALSE;
|
||||
|
||||
return NLS_EnumDateFormats(&ctxt);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* EnumDateFormatsW (KERNEL32.@)
|
||||
*/
|
||||
@@ -2058,19 +1849,7 @@ BOOL WINAPI EnumDateFormatsExEx(DATEFMT_ENUMPROCEXEX proc, const WCHAR *locale,
|
||||
}
|
||||
#endif /* _WIN32_WINNT >= 0x600 */
|
||||
|
||||
struct enumtimeformats_context {
|
||||
enum enum_callback_type type; /* callback kind */
|
||||
union {
|
||||
TIMEFMT_ENUMPROCW callback; /* user callback pointer */
|
||||
TIMEFMT_ENUMPROCEX callbackex;
|
||||
} u;
|
||||
LCID lcid; /* locale of interest */
|
||||
DWORD flags;
|
||||
LPARAM lParam;
|
||||
BOOL unicode; /* A vs W callback type, only for regular and Ex callbacks */
|
||||
};
|
||||
|
||||
static BOOL NLS_EnumTimeFormats(struct enumtimeformats_context *ctxt)
|
||||
BOOL NLS_EnumTimeFormats(struct enumtimeformats_context *ctxt)
|
||||
{
|
||||
WCHAR bufW[256];
|
||||
char bufA[256];
|
||||
@@ -2121,32 +1900,6 @@ static BOOL NLS_EnumTimeFormats(struct enumtimeformats_context *ctxt)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* EnumTimeFormatsA (KERNEL32.@)
|
||||
*
|
||||
* FIXME: MSDN mentions only LOCALE_USE_CP_ACP, should we handle
|
||||
* LOCALE_NOUSEROVERRIDE here as well?
|
||||
*/
|
||||
BOOL WINAPI EnumTimeFormatsA(TIMEFMT_ENUMPROCA proc, LCID lcid, DWORD flags)
|
||||
{
|
||||
struct enumtimeformats_context ctxt;
|
||||
|
||||
/* EnumTimeFormatsA doesn't support flags, EnumTimeFormatsW does. */
|
||||
if (flags & ~LOCALE_USE_CP_ACP)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_FLAGS);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ctxt.type = CALLBACK_ENUMPROC;
|
||||
ctxt.u.callback = (TIMEFMT_ENUMPROCW)proc;
|
||||
ctxt.lcid = lcid;
|
||||
ctxt.flags = flags;
|
||||
ctxt.unicode = FALSE;
|
||||
|
||||
return NLS_EnumTimeFormats(&ctxt);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* EnumTimeFormatsW (KERNEL32.@)
|
||||
*/
|
||||
@@ -2182,19 +1935,6 @@ BOOL WINAPI EnumTimeFormatsEx(TIMEFMT_ENUMPROCEX proc, const WCHAR *locale, DWOR
|
||||
}
|
||||
#endif /* _WIN32_WINNT >= 0x600 */
|
||||
|
||||
struct enumcalendar_context {
|
||||
enum enum_callback_type type; /* callback kind */
|
||||
union {
|
||||
CALINFO_ENUMPROCW callback; /* user callback pointer */
|
||||
CALINFO_ENUMPROCEXW callbackex;
|
||||
CALINFO_ENUMPROCEXEX callbackexex;
|
||||
} u;
|
||||
LCID lcid; /* locale of interest */
|
||||
CALID calendar; /* specific calendar or ENUM_ALL_CALENDARS */
|
||||
CALTYPE caltype; /* calendar information type */
|
||||
LPARAM lParam; /* user input parameter passed to callback, for ExEx case only */
|
||||
BOOL unicode; /* A vs W callback type, only for regular and Ex callbacks */
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
* NLS_EnumCalendarInfo <internal>
|
||||
@@ -2216,7 +1956,7 @@ struct enumcalendar_context {
|
||||
* TODO
|
||||
* The above note should be respected by GetCalendarInfoA.
|
||||
*/
|
||||
static BOOL NLS_EnumCalendarInfo(const struct enumcalendar_context *ctxt)
|
||||
BOOL NLS_EnumCalendarInfo(const struct enumcalendar_context *ctxt)
|
||||
{
|
||||
WCHAR *buf, *opt = NULL, *iter = NULL;
|
||||
CALID calendar = ctxt->calendar;
|
||||
@@ -2331,26 +2071,6 @@ cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* EnumCalendarInfoA [KERNEL32.@]
|
||||
*/
|
||||
BOOL WINAPI EnumCalendarInfoA( CALINFO_ENUMPROCA calinfoproc,LCID locale,
|
||||
CALID calendar,CALTYPE caltype )
|
||||
{
|
||||
struct enumcalendar_context ctxt;
|
||||
|
||||
TRACE("(%p,0x%08x,0x%08x,0x%08x)\n", calinfoproc, locale, calendar, caltype);
|
||||
|
||||
ctxt.type = CALLBACK_ENUMPROC;
|
||||
ctxt.u.callback = (CALINFO_ENUMPROCW)calinfoproc;
|
||||
ctxt.lcid = locale;
|
||||
ctxt.calendar = calendar;
|
||||
ctxt.caltype = caltype;
|
||||
ctxt.lParam = 0;
|
||||
ctxt.unicode = FALSE;
|
||||
return NLS_EnumCalendarInfo(&ctxt);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* EnumCalendarInfoW [KERNEL32.@]
|
||||
*/
|
||||
@@ -2374,22 +2094,6 @@ BOOL WINAPI EnumCalendarInfoW( CALINFO_ENUMPROCW calinfoproc,LCID locale,
|
||||
/******************************************************************************
|
||||
* EnumCalendarInfoExA [KERNEL32.@]
|
||||
*/
|
||||
BOOL WINAPI EnumCalendarInfoExA( CALINFO_ENUMPROCEXA calinfoproc,LCID locale,
|
||||
CALID calendar,CALTYPE caltype )
|
||||
{
|
||||
struct enumcalendar_context ctxt;
|
||||
|
||||
TRACE("(%p,0x%08x,0x%08x,0x%08x)\n", calinfoproc, locale, calendar, caltype);
|
||||
|
||||
ctxt.type = CALLBACK_ENUMPROCEX;
|
||||
ctxt.u.callbackex = (CALINFO_ENUMPROCEXW)calinfoproc;
|
||||
ctxt.lcid = locale;
|
||||
ctxt.calendar = calendar;
|
||||
ctxt.caltype = caltype;
|
||||
ctxt.lParam = 0;
|
||||
ctxt.unicode = FALSE;
|
||||
return NLS_EnumCalendarInfo(&ctxt);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* EnumCalendarInfoExW [KERNEL32.@]
|
||||
@@ -2433,61 +2137,6 @@ BOOL WINAPI EnumCalendarInfoExEx( CALINFO_ENUMPROCEXEX calinfoproc, LPCWSTR loca
|
||||
}
|
||||
#endif /* _WIN32_WINNT >= 0x600 */
|
||||
|
||||
/*********************************************************************
|
||||
* GetCalendarInfoA (KERNEL32.@)
|
||||
*
|
||||
*/
|
||||
int WINAPI GetCalendarInfoA(LCID lcid, CALID Calendar, CALTYPE CalType,
|
||||
LPSTR lpCalData, int cchData, LPDWORD lpValue)
|
||||
{
|
||||
int ret, cchDataW = cchData;
|
||||
LPWSTR lpCalDataW = NULL;
|
||||
#ifdef __REACTOS__
|
||||
DWORD cp = CP_ACP;
|
||||
if (!(CalType & CAL_USE_CP_ACP))
|
||||
{
|
||||
DWORD dwFlags = ((CalType & CAL_NOUSEROVERRIDE) ? LOCALE_NOUSEROVERRIDE : 0);
|
||||
const NLS_FORMAT_NODE *node = NLS_GetFormats(lcid, dwFlags);
|
||||
if (!node)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
cp = node->dwCodePage;
|
||||
}
|
||||
if ((CalType & 0xFFFF) == CAL_SABBREVERASTRING)
|
||||
{
|
||||
/* NOTE: CAL_SABBREVERASTRING is not supported in GetCalendarInfoA */
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (NLS_IsUnicodeOnlyLcid(lcid))
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!cchData && !(CalType & CAL_RETURN_NUMBER))
|
||||
cchDataW = GetCalendarInfoW(lcid, Calendar, CalType, NULL, 0, NULL);
|
||||
if (!(lpCalDataW = HeapAlloc(GetProcessHeap(), 0, cchDataW*sizeof(WCHAR))))
|
||||
return 0;
|
||||
|
||||
ret = GetCalendarInfoW(lcid, Calendar, CalType, lpCalDataW, cchDataW, lpValue);
|
||||
if(ret && lpCalDataW && lpCalData)
|
||||
#ifdef __REACTOS__
|
||||
ret = WideCharToMultiByte(cp, 0, lpCalDataW, -1, lpCalData, cchData, NULL, NULL);
|
||||
#else
|
||||
ret = WideCharToMultiByte(CP_ACP, 0, lpCalDataW, -1, lpCalData, cchData, NULL, NULL);
|
||||
#endif
|
||||
else if (CalType & CAL_RETURN_NUMBER)
|
||||
ret *= sizeof(WCHAR);
|
||||
HeapFree(GetProcessHeap(), 0, lpCalDataW);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* GetCalendarInfoW (KERNEL32.@)
|
||||
*
|
||||
@@ -2819,16 +2468,6 @@ int WINAPI GetCalendarInfoEx(LPCWSTR locale, CALID calendar, LPCWSTR lpReserved,
|
||||
}
|
||||
#endif
|
||||
|
||||
/*********************************************************************
|
||||
* SetCalendarInfoA (KERNEL32.@)
|
||||
*
|
||||
*/
|
||||
int WINAPI SetCalendarInfoA(LCID Locale, CALID Calendar, CALTYPE CalType, LPCSTR lpCalData)
|
||||
{
|
||||
FIXME("(%08x,%08x,%08x,%s): stub\n",
|
||||
Locale, Calendar, CalType, debugstr_a(lpCalData));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* SetCalendarInfoW (KERNEL32.@)
|
||||
|
||||
@@ -10,3 +10,57 @@
|
||||
|
||||
/*lcformat.c */
|
||||
extern BOOL NLS_IsUnicodeOnlyLcid(LCID);
|
||||
|
||||
/* Returns the ANSI codepage used by locale formatting when LOCALE_USE_CP_ACP is not set.
|
||||
* dwFlags should contain the LOCALE_ flags relevant to formatting (typically LOCALE_NOUSEROVERRIDE).
|
||||
*/
|
||||
extern DWORD NLS_GetAnsiCodePage(LCID lcid, DWORD dwFlags);
|
||||
|
||||
enum enum_callback_type {
|
||||
CALLBACK_ENUMPROC,
|
||||
CALLBACK_ENUMPROCEX,
|
||||
CALLBACK_ENUMPROCEXEX
|
||||
};
|
||||
|
||||
struct enumdateformats_context {
|
||||
enum enum_callback_type type; /* callback kind */
|
||||
union {
|
||||
DATEFMT_ENUMPROCW callback; /* user callback pointer */
|
||||
DATEFMT_ENUMPROCEXW callbackex;
|
||||
DATEFMT_ENUMPROCEXEX callbackexex;
|
||||
} u;
|
||||
LCID lcid; /* locale of interest */
|
||||
DWORD flags;
|
||||
LPARAM lParam;
|
||||
BOOL unicode; /* A vs W callback type, only for regular and Ex callbacks */
|
||||
};
|
||||
|
||||
struct enumtimeformats_context {
|
||||
enum enum_callback_type type; /* callback kind */
|
||||
union {
|
||||
TIMEFMT_ENUMPROCW callback; /* user callback pointer */
|
||||
TIMEFMT_ENUMPROCEX callbackex;
|
||||
} u;
|
||||
LCID lcid; /* locale of interest */
|
||||
DWORD flags;
|
||||
LPARAM lParam;
|
||||
BOOL unicode; /* A vs W callback type, only for regular and Ex callbacks */
|
||||
};
|
||||
|
||||
struct enumcalendar_context {
|
||||
enum enum_callback_type type; /* callback kind */
|
||||
union {
|
||||
CALINFO_ENUMPROCW callback; /* user callback pointer */
|
||||
CALINFO_ENUMPROCEXW callbackex;
|
||||
CALINFO_ENUMPROCEXEX callbackexex;
|
||||
} u;
|
||||
LCID lcid; /* locale of interest */
|
||||
CALID calendar; /* specific calendar or ENUM_ALL_CALENDARS */
|
||||
CALTYPE caltype; /* calendar information type */
|
||||
LPARAM lParam; /* user input parameter passed to callback, for ExEx case only */
|
||||
BOOL unicode; /* A vs W callback type, only for regular and Ex callbacks */
|
||||
};
|
||||
|
||||
extern BOOL NLS_EnumDateFormats(const struct enumdateformats_context *ctxt);
|
||||
extern BOOL NLS_EnumTimeFormats(struct enumtimeformats_context *ctxt);
|
||||
extern BOOL NLS_EnumCalendarInfo(const struct enumcalendar_context *ctxt);
|
||||
|
||||
@@ -0,0 +1,375 @@
|
||||
/*
|
||||
* Locale-dependent format handling
|
||||
*
|
||||
* Copyright 1995 Martin von Loewis
|
||||
* Copyright 1998 David Lee Lambert
|
||||
* Copyright 2000 Julio Cesar Gazquez
|
||||
* Copyright 2003 Jon Griffiths
|
||||
* Copyright 2005 Dmitry Timoshkov
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <k32.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
DEBUG_CHANNEL(nls);
|
||||
|
||||
#include "lcformat_private.h"
|
||||
|
||||
#ifndef CAL_SABBREVERASTRING
|
||||
#define CAL_SABBREVERASTRING 0x00000039
|
||||
#endif
|
||||
|
||||
/**************************************************************************
|
||||
* GetNumberFormatA (KERNEL32.@)
|
||||
*
|
||||
* Format a number string for a given locale.
|
||||
*
|
||||
* PARAMS
|
||||
* lcid [I] Locale to format for
|
||||
* dwFlags [I] LOCALE_ flags from "winnls.h"
|
||||
* lpszValue [I] String to format
|
||||
* lpFormat [I] Formatting overrides
|
||||
* lpNumberStr [O] Destination for formatted string
|
||||
* cchOut [I] Size of lpNumberStr, or 0 to calculate the resulting size
|
||||
*
|
||||
* NOTES
|
||||
* - lpszValue can contain only '0' - '9', '-' and '.'.
|
||||
* - If lpFormat is non-NULL, dwFlags must be 0. In this case lpszValue will
|
||||
* be formatted according to the format details returned by GetLocaleInfoA().
|
||||
* - This function rounds the number string if the number of decimals exceeds the
|
||||
* locales normal number of decimal places.
|
||||
* - If cchOut is 0, this function does not write to lpNumberStr.
|
||||
* - The Ascii version of this function fails if lcid is Unicode only.
|
||||
*
|
||||
* RETURNS
|
||||
* Success: The number of character written to lpNumberStr, or that would
|
||||
* have been written, if cchOut is 0.
|
||||
* Failure: 0. Use GetLastError() to determine the cause.
|
||||
*/
|
||||
|
||||
/**************************************************************************
|
||||
* GetNumberFormatA (KERNEL32.@)
|
||||
*/
|
||||
INT WINAPI GetNumberFormatA(LCID lcid, DWORD dwFlags,
|
||||
LPCSTR lpszValue, const NUMBERFMTA *lpFormat,
|
||||
LPSTR lpNumberStr, int cchOut)
|
||||
{
|
||||
DWORD cp = CP_ACP;
|
||||
WCHAR szDec[8], szGrp[8], szIn[128], szOut[128];
|
||||
NUMBERFMTW fmt;
|
||||
const NUMBERFMTW *pfmt = NULL;
|
||||
INT iRet;
|
||||
|
||||
TRACE("(0x%04x,0x%08x,%s,%p,%p,%d)\n", lcid, dwFlags, debugstr_a(lpszValue),
|
||||
lpFormat, lpNumberStr, cchOut);
|
||||
|
||||
if (NLS_IsUnicodeOnlyLcid(lcid))
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(dwFlags & LOCALE_USE_CP_ACP))
|
||||
{
|
||||
cp = NLS_GetAnsiCodePage(lcid, dwFlags);
|
||||
if (!cp)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (lpFormat)
|
||||
{
|
||||
memcpy(&fmt, lpFormat, sizeof(fmt));
|
||||
pfmt = &fmt;
|
||||
if (lpFormat->lpDecimalSep)
|
||||
{
|
||||
MultiByteToWideChar(cp, 0, lpFormat->lpDecimalSep, -1, szDec, ARRAY_SIZE(szDec));
|
||||
fmt.lpDecimalSep = szDec;
|
||||
}
|
||||
if (lpFormat->lpThousandSep)
|
||||
{
|
||||
MultiByteToWideChar(cp, 0, lpFormat->lpThousandSep, -1, szGrp, ARRAY_SIZE(szGrp));
|
||||
fmt.lpThousandSep = szGrp;
|
||||
}
|
||||
}
|
||||
|
||||
if (lpszValue)
|
||||
MultiByteToWideChar(cp, 0, lpszValue, -1, szIn, ARRAY_SIZE(szIn));
|
||||
|
||||
if (cchOut > (int) ARRAY_SIZE(szOut))
|
||||
cchOut = ARRAY_SIZE(szOut);
|
||||
|
||||
szOut[0] = '\0';
|
||||
|
||||
iRet = GetNumberFormatW(lcid, dwFlags, lpszValue ? szIn : NULL, pfmt,
|
||||
lpNumberStr ? szOut : NULL, cchOut);
|
||||
|
||||
if (szOut[0] && lpNumberStr)
|
||||
WideCharToMultiByte(cp, 0, szOut, -1, lpNumberStr, cchOut, 0, 0);
|
||||
return iRet;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* GetCurrencyFormatA (KERNEL32.@)
|
||||
*
|
||||
* Format a currency string for a given locale.
|
||||
*
|
||||
* PARAMS
|
||||
* lcid [I] Locale to format for
|
||||
* dwFlags [I] LOCALE_ flags from "winnls.h"
|
||||
* lpszValue [I] String to format
|
||||
* lpFormat [I] Formatting overrides
|
||||
* lpCurrencyStr [O] Destination for formatted string
|
||||
* cchOut [I] Size of lpCurrencyStr, or 0 to calculate the resulting size
|
||||
*
|
||||
* NOTES
|
||||
* - lpszValue can contain only '0' - '9', '-' and '.'.
|
||||
* - If lpFormat is non-NULL, dwFlags must be 0. In this case lpszValue will
|
||||
* be formatted according to the format details returned by GetLocaleInfoA().
|
||||
* - This function rounds the currency if the number of decimals exceeds the
|
||||
* locales number of currency decimal places.
|
||||
* - If cchOut is 0, this function does not write to lpCurrencyStr.
|
||||
* - The Ascii version of this function fails if lcid is Unicode only.
|
||||
*
|
||||
* RETURNS
|
||||
* Success: The number of character written to lpNumberStr, or that would
|
||||
* have been written, if cchOut is 0.
|
||||
* Failure: 0. Use GetLastError() to determine the cause.
|
||||
*/
|
||||
|
||||
/**************************************************************************
|
||||
* GetCurrencyFormatA (KERNEL32.@)
|
||||
*/
|
||||
INT WINAPI GetCurrencyFormatA(LCID lcid, DWORD dwFlags,
|
||||
LPCSTR lpszValue, const CURRENCYFMTA *lpFormat,
|
||||
LPSTR lpCurrencyStr, int cchOut)
|
||||
{
|
||||
DWORD cp = CP_ACP;
|
||||
WCHAR szDec[8], szGrp[8], szCy[8], szIn[128], szOut[128];
|
||||
CURRENCYFMTW fmt;
|
||||
const CURRENCYFMTW *pfmt = NULL;
|
||||
INT iRet;
|
||||
|
||||
TRACE("(0x%04x,0x%08x,%s,%p,%p,%d)\n", lcid, dwFlags, debugstr_a(lpszValue),
|
||||
lpFormat, lpCurrencyStr, cchOut);
|
||||
|
||||
if (NLS_IsUnicodeOnlyLcid(lcid))
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(dwFlags & LOCALE_USE_CP_ACP))
|
||||
{
|
||||
cp = NLS_GetAnsiCodePage(lcid, dwFlags);
|
||||
if (!cp)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (lpFormat)
|
||||
{
|
||||
memcpy(&fmt, lpFormat, sizeof(fmt));
|
||||
pfmt = &fmt;
|
||||
if (lpFormat->lpDecimalSep)
|
||||
{
|
||||
MultiByteToWideChar(cp, 0, lpFormat->lpDecimalSep, -1, szDec, ARRAY_SIZE(szDec));
|
||||
fmt.lpDecimalSep = szDec;
|
||||
}
|
||||
if (lpFormat->lpThousandSep)
|
||||
{
|
||||
MultiByteToWideChar(cp, 0, lpFormat->lpThousandSep, -1, szGrp, ARRAY_SIZE(szGrp));
|
||||
fmt.lpThousandSep = szGrp;
|
||||
}
|
||||
if (lpFormat->lpCurrencySymbol)
|
||||
{
|
||||
MultiByteToWideChar(cp, 0, lpFormat->lpCurrencySymbol, -1, szCy, ARRAY_SIZE(szCy));
|
||||
fmt.lpCurrencySymbol = szCy;
|
||||
}
|
||||
}
|
||||
|
||||
if (lpszValue)
|
||||
MultiByteToWideChar(cp, 0, lpszValue, -1, szIn, ARRAY_SIZE(szIn));
|
||||
|
||||
if (cchOut > (int) ARRAY_SIZE(szOut))
|
||||
cchOut = ARRAY_SIZE(szOut);
|
||||
|
||||
szOut[0] = '\0';
|
||||
|
||||
iRet = GetCurrencyFormatW(lcid, dwFlags, lpszValue ? szIn : NULL, pfmt,
|
||||
lpCurrencyStr ? szOut : NULL, cchOut);
|
||||
|
||||
if (szOut[0] && lpCurrencyStr)
|
||||
WideCharToMultiByte(cp, 0, szOut, -1, lpCurrencyStr, cchOut, 0, 0);
|
||||
return iRet;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* EnumDateFormatsA (KERNEL32.@)
|
||||
*
|
||||
* FIXME: MSDN mentions only LOCALE_USE_CP_ACP, should we handle
|
||||
* LOCALE_NOUSEROVERRIDE here as well?
|
||||
*/
|
||||
BOOL WINAPI EnumDateFormatsA(DATEFMT_ENUMPROCA proc, LCID lcid, DWORD flags)
|
||||
{
|
||||
struct enumdateformats_context ctxt;
|
||||
|
||||
ctxt.type = CALLBACK_ENUMPROC;
|
||||
ctxt.u.callback = (DATEFMT_ENUMPROCW)proc;
|
||||
ctxt.lcid = lcid;
|
||||
ctxt.flags = flags;
|
||||
ctxt.unicode = FALSE;
|
||||
|
||||
return NLS_EnumDateFormats(&ctxt);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* EnumTimeFormatsA (KERNEL32.@)
|
||||
*
|
||||
* FIXME: MSDN mentions only LOCALE_USE_CP_ACP, should we handle
|
||||
* LOCALE_NOUSEROVERRIDE here as well?
|
||||
*/
|
||||
BOOL WINAPI EnumTimeFormatsA(TIMEFMT_ENUMPROCA proc, LCID lcid, DWORD flags)
|
||||
{
|
||||
struct enumtimeformats_context ctxt;
|
||||
|
||||
/* EnumTimeFormatsA doesn't support flags, EnumTimeFormatsW does. */
|
||||
if (flags & ~LOCALE_USE_CP_ACP)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_FLAGS);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ctxt.type = CALLBACK_ENUMPROC;
|
||||
ctxt.u.callback = (TIMEFMT_ENUMPROCW)proc;
|
||||
ctxt.lcid = lcid;
|
||||
ctxt.flags = flags;
|
||||
ctxt.unicode = FALSE;
|
||||
|
||||
return NLS_EnumTimeFormats(&ctxt);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* EnumCalendarInfoA [KERNEL32.@]
|
||||
*/
|
||||
|
||||
BOOL WINAPI EnumCalendarInfoA(CALINFO_ENUMPROCA calinfoproc, LCID locale,
|
||||
CALID calendar, CALTYPE caltype)
|
||||
{
|
||||
struct enumcalendar_context ctxt;
|
||||
|
||||
TRACE("(%p,0x%08x,0x%08x,0x%08x)\n", calinfoproc, locale, calendar, caltype);
|
||||
|
||||
ctxt.type = CALLBACK_ENUMPROC;
|
||||
ctxt.u.callback = (CALINFO_ENUMPROCW)calinfoproc;
|
||||
ctxt.lcid = locale;
|
||||
ctxt.calendar = calendar;
|
||||
ctxt.caltype = caltype;
|
||||
ctxt.lParam = 0;
|
||||
ctxt.unicode = FALSE;
|
||||
return NLS_EnumCalendarInfo(&ctxt);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* EnumCalendarInfoExA [KERNEL32.@]
|
||||
*/
|
||||
BOOL WINAPI EnumCalendarInfoExA(CALINFO_ENUMPROCEXA calinfoproc, LCID locale,
|
||||
CALID calendar, CALTYPE caltype)
|
||||
{
|
||||
struct enumcalendar_context ctxt;
|
||||
|
||||
TRACE("(%p,0x%08x,0x%08x,0x%08x)\n", calinfoproc, locale, calendar, caltype);
|
||||
|
||||
ctxt.type = CALLBACK_ENUMPROCEX;
|
||||
ctxt.u.callbackex = (CALINFO_ENUMPROCEXW)calinfoproc;
|
||||
ctxt.lcid = locale;
|
||||
ctxt.calendar = calendar;
|
||||
ctxt.caltype = caltype;
|
||||
ctxt.lParam = 0;
|
||||
ctxt.unicode = FALSE;
|
||||
return NLS_EnumCalendarInfo(&ctxt);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* GetCalendarInfoA (KERNEL32.@)
|
||||
*/
|
||||
int WINAPI GetCalendarInfoA(LCID lcid, CALID Calendar, CALTYPE CalType,
|
||||
LPSTR lpCalData, int cchData, LPDWORD lpValue)
|
||||
{
|
||||
int ret, cchDataW = cchData;
|
||||
LPWSTR lpCalDataW = NULL;
|
||||
#ifdef __REACTOS__
|
||||
DWORD cp = CP_ACP;
|
||||
if (!(CalType & CAL_USE_CP_ACP))
|
||||
{
|
||||
DWORD dwFlags = ((CalType & CAL_NOUSEROVERRIDE) ? LOCALE_NOUSEROVERRIDE : 0);
|
||||
cp = NLS_GetAnsiCodePage(lcid, dwFlags);
|
||||
if (!cp)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if ((CalType & 0xFFFF) == CAL_SABBREVERASTRING)
|
||||
{
|
||||
/* NOTE: CAL_SABBREVERASTRING is not supported in GetCalendarInfoA */
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (NLS_IsUnicodeOnlyLcid(lcid))
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!cchData && !(CalType & CAL_RETURN_NUMBER))
|
||||
cchDataW = GetCalendarInfoW(lcid, Calendar, CalType, NULL, 0, NULL);
|
||||
if (!(lpCalDataW = HeapAlloc(GetProcessHeap(), 0, cchDataW*sizeof(WCHAR))))
|
||||
return 0;
|
||||
|
||||
ret = GetCalendarInfoW(lcid, Calendar, CalType, lpCalDataW, cchDataW, lpValue);
|
||||
if(ret && lpCalDataW && lpCalData)
|
||||
#ifdef __REACTOS__
|
||||
ret = WideCharToMultiByte(cp, 0, lpCalDataW, -1, lpCalData, cchData, NULL, NULL);
|
||||
#else
|
||||
ret = WideCharToMultiByte(CP_ACP, 0, lpCalDataW, -1, lpCalData, cchData, NULL, NULL);
|
||||
#endif
|
||||
else if (CalType & CAL_RETURN_NUMBER)
|
||||
ret *= sizeof(WCHAR);
|
||||
HeapFree(GetProcessHeap(), 0, lpCalDataW);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* SetCalendarInfoA (KERNEL32.@)
|
||||
*/
|
||||
int WINAPI SetCalendarInfoA(LCID Locale, CALID Calendar, CALTYPE CalType, LPCSTR lpCalData)
|
||||
{
|
||||
FIXME("(%08x,%08x,%08x,%s): stub\n",
|
||||
Locale, Calendar, CalType, debugstr_a(lpCalData));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
@@ -3903,77 +3903,6 @@ map_string_exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* FoldStringA (KERNEL32.@)
|
||||
*
|
||||
* Map characters in a string.
|
||||
*
|
||||
* PARAMS
|
||||
* dwFlags [I] Flags controlling chars to map (MAP_ constants from "winnls.h")
|
||||
* src [I] String to map
|
||||
* srclen [I] Length of src, or -1 if src is NUL terminated
|
||||
* dst [O] Destination for mapped string
|
||||
* dstlen [I] Length of dst, or 0 to find the required length for the mapped string
|
||||
*
|
||||
* RETURNS
|
||||
* Success: The length of the string written to dst, including the terminating NUL. If
|
||||
* dstlen is 0, the value returned is the same, but nothing is written to dst,
|
||||
* and dst may be NULL.
|
||||
* Failure: 0. Use GetLastError() to determine the cause.
|
||||
*/
|
||||
INT WINAPI FoldStringA(DWORD dwFlags, LPCSTR src, INT srclen,
|
||||
LPSTR dst, INT dstlen)
|
||||
{
|
||||
INT ret = 0, srclenW = 0;
|
||||
WCHAR *srcW = NULL, *dstW = NULL;
|
||||
|
||||
if (!src || !srclen || dstlen < 0 || (dstlen && !dst) || src == dst)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
srclenW = MultiByteToWideChar(CP_ACP, dwFlags & MAP_COMPOSITE ? MB_COMPOSITE : 0,
|
||||
src, srclen, NULL, 0);
|
||||
srcW = HeapAlloc(GetProcessHeap(), 0, srclenW * sizeof(WCHAR));
|
||||
|
||||
if (!srcW)
|
||||
{
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
goto FoldStringA_exit;
|
||||
}
|
||||
|
||||
MultiByteToWideChar(CP_ACP, dwFlags & MAP_COMPOSITE ? MB_COMPOSITE : 0,
|
||||
src, srclen, srcW, srclenW);
|
||||
|
||||
dwFlags = (dwFlags & ~MAP_PRECOMPOSED) | MAP_FOLDCZONE;
|
||||
|
||||
ret = FoldStringW(dwFlags, srcW, srclenW, NULL, 0);
|
||||
if (ret && dstlen)
|
||||
{
|
||||
dstW = HeapAlloc(GetProcessHeap(), 0, ret * sizeof(WCHAR));
|
||||
|
||||
if (!dstW)
|
||||
{
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
goto FoldStringA_exit;
|
||||
}
|
||||
|
||||
ret = FoldStringW(dwFlags, srcW, srclenW, dstW, ret);
|
||||
if (!WideCharToMultiByte(CP_ACP, 0, dstW, ret, dst, dstlen, NULL, NULL))
|
||||
{
|
||||
ret = 0;
|
||||
SetLastError(ERROR_INSUFFICIENT_BUFFER);
|
||||
}
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, dstW);
|
||||
|
||||
FoldStringA_exit:
|
||||
HeapFree(GetProcessHeap(), 0, srcW);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* FoldStringW (KERNEL32.@)
|
||||
*
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Locale support
|
||||
*
|
||||
* Copyright 1995 Martin von Loewis
|
||||
* Copyright 1998 David Lee Lambert
|
||||
* Copyright 2000 Julio Cesar Gazquez
|
||||
* Copyright 2002 Alexandre Julliard for CodeWeavers
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <k32.h>
|
||||
|
||||
/*************************************************************************
|
||||
* FoldStringA (KERNEL32.@)
|
||||
*
|
||||
* Map characters in a string.
|
||||
*
|
||||
* PARAMS
|
||||
* dwFlags [I] Flags controlling chars to map (MAP_ constants from "winnls.h")
|
||||
* src [I] String to map
|
||||
* srclen [I] Length of src, or -1 if src is NUL terminated
|
||||
* dst [O] Destination for mapped string
|
||||
* dstlen [I] Length of dst, or 0 to find the required length for the mapped string
|
||||
*
|
||||
* RETURNS
|
||||
* Success: The length of the string written to dst, including the terminating NUL. If
|
||||
* dstlen is 0, the value returned is the same, but nothing is written to dst,
|
||||
* and dst may be NULL.
|
||||
* Failure: 0. Use GetLastError() to determine the cause.
|
||||
*/
|
||||
INT WINAPI FoldStringA(DWORD dwFlags, LPCSTR src, INT srclen,
|
||||
LPSTR dst, INT dstlen)
|
||||
{
|
||||
INT ret = 0, srclenW = 0;
|
||||
WCHAR *srcW = NULL, *dstW = NULL;
|
||||
|
||||
if (!src || !srclen || dstlen < 0 || (dstlen && !dst) || src == dst)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
srclenW = MultiByteToWideChar(CP_ACP, dwFlags & MAP_COMPOSITE ? MB_COMPOSITE : 0,
|
||||
src, srclen, NULL, 0);
|
||||
srcW = HeapAlloc(GetProcessHeap(), 0, srclenW * sizeof(WCHAR));
|
||||
|
||||
if (!srcW)
|
||||
{
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
goto FoldStringA_exit;
|
||||
}
|
||||
|
||||
MultiByteToWideChar(CP_ACP, dwFlags & MAP_COMPOSITE ? MB_COMPOSITE : 0,
|
||||
src, srclen, srcW, srclenW);
|
||||
|
||||
dwFlags = (dwFlags & ~MAP_PRECOMPOSED) | MAP_FOLDCZONE;
|
||||
|
||||
ret = FoldStringW(dwFlags, srcW, srclenW, NULL, 0);
|
||||
if (ret && dstlen)
|
||||
{
|
||||
dstW = HeapAlloc(GetProcessHeap(), 0, ret * sizeof(WCHAR));
|
||||
|
||||
if (!dstW)
|
||||
{
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
goto FoldStringA_exit;
|
||||
}
|
||||
|
||||
ret = FoldStringW(dwFlags, srcW, srclenW, dstW, ret);
|
||||
if (!WideCharToMultiByte(CP_ACP, 0, dstW, ret, dst, dstlen, NULL, NULL))
|
||||
{
|
||||
ret = 0;
|
||||
SetLastError(ERROR_INSUFFICIENT_BUFFER);
|
||||
}
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, dstW);
|
||||
|
||||
FoldStringA_exit:
|
||||
HeapFree(GetProcessHeap(), 0, srcW);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
Reference in New Issue
Block a user