From c81bc9f21ea6f572baf0edbf0592a3c5daeadc6d Mon Sep 17 00:00:00 2001 From: Justin Miller Date: Fri, 13 Feb 2026 20:13:23 -0800 Subject: [PATCH] [KERNEL32] Split off some ANSI functions from the bulk of Kernel32 (#8555) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [KERNEL32] Split off some ANSI functions from the bulk of Kernel32 Co-authored-by: Hermès BÉLUSCA - MAÏTO --- dll/win32/kernel32/CMakeLists.txt | 14 + dll/win32/kernel32/client/atom.c | 20 - dll/win32/kernel32/client/atomansi.c | 38 ++ dll/win32/kernel32/client/file/copy.c | 74 ---- dll/win32/kernel32/client/file/copyansi.c | 87 ++++ dll/win32/kernel32/client/file/dir.c | 32 -- dll/win32/kernel32/client/file/diransi.c | 48 +++ dll/win32/kernel32/client/file/fileinfo.c | 16 - dll/win32/kernel32/client/file/fileinfoansi.c | 36 ++ dll/win32/kernel32/client/file/mntpoint.c | 65 --- dll/win32/kernel32/client/file/mntpointansi.c | 79 ++++ dll/win32/kernel32/client/file/move.c | 141 ------- dll/win32/kernel32/client/file/moveansi.c | 157 +++++++ dll/win32/kernel32/client/file/volume.c | 64 --- dll/win32/kernel32/client/file/volumeansi.c | 78 ++++ dll/win32/kernel32/client/path.c | 81 ---- dll/win32/kernel32/client/pathansi.c | 96 +++++ dll/win32/kernel32/client/proc.c | 352 ---------------- dll/win32/kernel32/client/procansi.c | 394 ++++++++++++++++++ dll/win32/kernel32/client/synch.c | 64 --- dll/win32/kernel32/client/synchansi.c | 78 ++++ dll/win32/kernel32/client/sysinfo.c | 27 -- dll/win32/kernel32/client/sysinfoansi.c | 61 +++ dll/win32/kernel32/client/utils.c | 1 + dll/win32/kernel32/client/version.c | 25 -- dll/win32/kernel32/client/versionansi.c | 39 ++ dll/win32/kernel32/winnls/string/lcformat.c | 393 +---------------- .../kernel32/winnls/string/lcformat_private.h | 54 +++ .../kernel32/winnls/string/lcformatansi.c | 375 +++++++++++++++++ dll/win32/kernel32/winnls/string/locale.c | 71 ---- dll/win32/kernel32/winnls/string/localeansi.c | 97 +++++ 31 files changed, 1748 insertions(+), 1409 deletions(-) create mode 100644 dll/win32/kernel32/client/atomansi.c create mode 100644 dll/win32/kernel32/client/file/copyansi.c create mode 100644 dll/win32/kernel32/client/file/diransi.c create mode 100644 dll/win32/kernel32/client/file/fileinfoansi.c create mode 100644 dll/win32/kernel32/client/file/mntpointansi.c create mode 100644 dll/win32/kernel32/client/file/moveansi.c create mode 100644 dll/win32/kernel32/client/file/volumeansi.c create mode 100644 dll/win32/kernel32/client/pathansi.c create mode 100644 dll/win32/kernel32/client/procansi.c create mode 100644 dll/win32/kernel32/client/synchansi.c create mode 100644 dll/win32/kernel32/client/sysinfoansi.c create mode 100644 dll/win32/kernel32/client/versionansi.c create mode 100644 dll/win32/kernel32/winnls/string/lcformatansi.c create mode 100644 dll/win32/kernel32/winnls/string/localeansi.c diff --git a/dll/win32/kernel32/CMakeLists.txt b/dll/win32/kernel32/CMakeLists.txt index b037e697800..115e48598c5 100644 --- a/dll/win32/kernel32/CMakeLists.txt +++ b/dll/win32/kernel32/CMakeLists.txt @@ -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 diff --git a/dll/win32/kernel32/client/atom.c b/dll/win32/kernel32/client/atom.c index 874646414b8..363057f49d2 100644 --- a/dll/win32/kernel32/client/atom.c +++ b/dll/win32/kernel32/client/atom.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 */ diff --git a/dll/win32/kernel32/client/atomansi.c b/dll/win32/kernel32/client/atomansi.c new file mode 100644 index 00000000000..e4a2e44ae9b --- /dev/null +++ b/dll/win32/kernel32/client/atomansi.c @@ -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 + +/* 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 */ diff --git a/dll/win32/kernel32/client/file/copy.c b/dll/win32/kernel32/client/file/copy.c index 7213611b6ab..9df97ba1596 100644 --- a/dll/win32/kernel32/client/file/copy.c +++ b/dll/win32/kernel32/client/file/copy.c @@ -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 */ diff --git a/dll/win32/kernel32/client/file/copyansi.c b/dll/win32/kernel32/client/file/copyansi.c new file mode 100644 index 00000000000..b3d252da9d8 --- /dev/null +++ b/dll/win32/kernel32/client/file/copyansi.c @@ -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 (ariadne@xs4all.nl) + */ + +/* INCLUDES ****************************************************************/ + +#include + +/* 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 */ diff --git a/dll/win32/kernel32/client/file/dir.c b/dll/win32/kernel32/client/file/dir.c index b4594fc5830..aca4c31fbcd 100644 --- a/dll/win32/kernel32/client/file/dir.c +++ b/dll/win32/kernel32/client/file/dir.c @@ -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 diff --git a/dll/win32/kernel32/client/file/diransi.c b/dll/win32/kernel32/client/file/diransi.c new file mode 100644 index 00000000000..6046feb6380 --- /dev/null +++ b/dll/win32/kernel32/client/file/diransi.c @@ -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 (pierre@reactos.org) + */ + +/* INCLUDES ******************************************************************/ + +#include + +/* 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 */ diff --git a/dll/win32/kernel32/client/file/fileinfo.c b/dll/win32/kernel32/client/file/fileinfo.c index b70a99a137c..c4596796c28 100644 --- a/dll/win32/kernel32/client/file/fileinfo.c +++ b/dll/win32/kernel32/client/file/fileinfo.c @@ -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 */ diff --git a/dll/win32/kernel32/client/file/fileinfoansi.c b/dll/win32/kernel32/client/file/fileinfoansi.c new file mode 100644 index 00000000000..104fef2a057 --- /dev/null +++ b/dll/win32/kernel32/client/file/fileinfoansi.c @@ -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 ( ariadne@xs4all.nl) + * Pierre Schweitzer (pierre.schweitzer@reactos.org) + * UPDATE HISTORY: + * Created 01/11/98 + */ + +/* INCLUDES *****************************************************************/ + +#include + +/* 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 */ diff --git a/dll/win32/kernel32/client/file/mntpoint.c b/dll/win32/kernel32/client/file/mntpoint.c index 8fab74c9a8d..798926e2d5a 100644 --- a/dll/win32/kernel32/client/file/mntpoint.c +++ b/dll/win32/kernel32/client/file/mntpoint.c @@ -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 */ diff --git a/dll/win32/kernel32/client/file/mntpointansi.c b/dll/win32/kernel32/client/file/mntpointansi.c new file mode 100644 index 00000000000..9d4cbf55c2c --- /dev/null +++ b/dll/win32/kernel32/client/file/mntpointansi.c @@ -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 + +/* 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 */ diff --git a/dll/win32/kernel32/client/file/move.c b/dll/win32/kernel32/client/file/move.c index 51d2211b61b..74bfbb493ea 100644 --- a/dll/win32/kernel32/client/file/move.c +++ b/dll/win32/kernel32/client/file/move.c @@ -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 */ diff --git a/dll/win32/kernel32/client/file/moveansi.c b/dll/win32/kernel32/client/file/moveansi.c new file mode 100644 index 00000000000..6f118e405f0 --- /dev/null +++ b/dll/win32/kernel32/client/file/moveansi.c @@ -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 ( ariadne@xs4all.nl) + * Gerhard W. Gruber (sparhawk_at_gmx.at) + * Dmitry Philippov (shedon@mail.ru) + * Pierre Schweitzer (pierre@reactos.org) + */ + +/* INCLUDES *****************************************************************/ + +#include + +/* 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 */ diff --git a/dll/win32/kernel32/client/file/volume.c b/dll/win32/kernel32/client/file/volume.c index 8ceb23865c6..a68cd1a8448 100644 --- a/dll/win32/kernel32/client/file/volume.c +++ b/dll/win32/kernel32/client/file/volume.c @@ -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 */ diff --git a/dll/win32/kernel32/client/file/volumeansi.c b/dll/win32/kernel32/client/file/volumeansi.c new file mode 100644 index 00000000000..4a83786a25f --- /dev/null +++ b/dll/win32/kernel32/client/file/volumeansi.c @@ -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 + +/* 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 */ diff --git a/dll/win32/kernel32/client/path.c b/dll/win32/kernel32/client/path.c index ea014bb512d..016b0c87995 100644 --- a/dll/win32/kernel32/client/path.c +++ b/dll/win32/kernel32/client/path.c @@ -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 */ diff --git a/dll/win32/kernel32/client/pathansi.c b/dll/win32/kernel32/client/pathansi.c new file mode 100644 index 00000000000..d78e6a26cac --- /dev/null +++ b/dll/win32/kernel32/client/pathansi.c @@ -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 (alex.ionescu@reactos.org) + */ + +/* INCLUDES *******************************************************************/ + +#include + +/* 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 */ diff --git a/dll/win32/kernel32/client/proc.c b/dll/win32/kernel32/client/proc.c index fa46a892132..9ade5f98ca1 100644 --- a/dll/win32/kernel32/client/proc.c +++ b/dll/win32/kernel32/client/proc.c @@ -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 */ diff --git a/dll/win32/kernel32/client/procansi.c b/dll/win32/kernel32/client/procansi.c new file mode 100644 index 00000000000..2d9753da841 --- /dev/null +++ b/dll/win32/kernel32/client/procansi.c @@ -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 (ariadne@xs4all.nl) + * UPDATE HISTORY: + * Created 01/11/98 + */ + +/* INCLUDES ****************************************************************/ + +#include +#define NDEBUG +#include + +/* 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 */ diff --git a/dll/win32/kernel32/client/synch.c b/dll/win32/kernel32/client/synch.c index 2c0e9a7f063..53a145b6a00 100644 --- a/dll/win32/kernel32/client/synch.c +++ b/dll/win32/kernel32/client/synch.c @@ -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 */ diff --git a/dll/win32/kernel32/client/synchansi.c b/dll/win32/kernel32/client/synchansi.c new file mode 100644 index 00000000000..a57d504d16c --- /dev/null +++ b/dll/win32/kernel32/client/synchansi.c @@ -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 + +/* 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 */ diff --git a/dll/win32/kernel32/client/sysinfo.c b/dll/win32/kernel32/client/sysinfo.c index a17aa193227..110a113bdf9 100644 --- a/dll/win32/kernel32/client/sysinfo.c +++ b/dll/win32/kernel32/client/sysinfo.c @@ -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 diff --git a/dll/win32/kernel32/client/sysinfoansi.c b/dll/win32/kernel32/client/sysinfoansi.c new file mode 100644 index 00000000000..a93532e5a32 --- /dev/null +++ b/dll/win32/kernel32/client/sysinfoansi.c @@ -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 + +/* 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 */ diff --git a/dll/win32/kernel32/client/utils.c b/dll/win32/kernel32/client/utils.c index 54a6f05fa5c..047fbec9fc2 100644 --- a/dll/win32/kernel32/client/utils.c +++ b/dll/win32/kernel32/client/utils.c @@ -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; diff --git a/dll/win32/kernel32/client/version.c b/dll/win32/kernel32/client/version.c index b335210510a..19f08fdac36 100644 --- a/dll/win32/kernel32/client/version.c +++ b/dll/win32/kernel32/client/version.c @@ -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); -} diff --git a/dll/win32/kernel32/client/versionansi.c b/dll/win32/kernel32/client/versionansi.c new file mode 100644 index 00000000000..5554b03d7d6 --- /dev/null +++ b/dll/win32/kernel32/client/versionansi.c @@ -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 + +/* 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 */ diff --git a/dll/win32/kernel32/winnls/string/lcformat.c b/dll/win32/kernel32/winnls/string/lcformat.c index 25a5e4e3259..6072c2504aa 100644 --- a/dll/win32/kernel32/winnls/string/lcformat.c +++ b/dll/win32/kernel32/winnls/string/lcformat.c @@ -27,6 +27,8 @@ #include #include "japanese.h" /* Japanese eras */ +#include "lcformat_private.h" + #define NDEBUG #include DEBUG_CHANNEL(nls); @@ -352,6 +354,16 @@ static const NLS_FORMAT_NODE *NLS_GetFormats(LCID lcid, DWORD dwFlags) return node; } +/* + * NLS_GetAnsiCodePage + * 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 * @@ -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 @@ -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 @@ -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.@) diff --git a/dll/win32/kernel32/winnls/string/lcformat_private.h b/dll/win32/kernel32/winnls/string/lcformat_private.h index 00848222b59..89600e04c6d 100644 --- a/dll/win32/kernel32/winnls/string/lcformat_private.h +++ b/dll/win32/kernel32/winnls/string/lcformat_private.h @@ -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); diff --git a/dll/win32/kernel32/winnls/string/lcformatansi.c b/dll/win32/kernel32/winnls/string/lcformatansi.c new file mode 100644 index 00000000000..e4f6bd66a32 --- /dev/null +++ b/dll/win32/kernel32/winnls/string/lcformatansi.c @@ -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 + +#define NDEBUG +#include +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 */ diff --git a/dll/win32/kernel32/winnls/string/locale.c b/dll/win32/kernel32/winnls/string/locale.c index 416a27df1db..d30725f42cd 100644 --- a/dll/win32/kernel32/winnls/string/locale.c +++ b/dll/win32/kernel32/winnls/string/locale.c @@ -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.@) * diff --git a/dll/win32/kernel32/winnls/string/localeansi.c b/dll/win32/kernel32/winnls/string/localeansi.c new file mode 100644 index 00000000000..27af19551b3 --- /dev/null +++ b/dll/win32/kernel32/winnls/string/localeansi.c @@ -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 + +/************************************************************************* + * 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 */